mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-13 02:32:09 +10:00
@@ -24,11 +24,13 @@ package org.diylc.common;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.diylc.core.annotations.Indexed;
|
||||
import org.diylc.netlist.Netlist;
|
||||
import org.diylc.netlist.Node;
|
||||
import org.diylc.netlist.Summary;
|
||||
import org.diylc.netlist.TreeException;
|
||||
|
||||
@Indexed
|
||||
public interface INetlistAnalyzer {
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.util.UUID;
|
||||
|
||||
import org.diylc.core.annotations.ComponentDescriptor;
|
||||
import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.Indexed;
|
||||
|
||||
/**
|
||||
* Interface for component instance. Implementation classes of this interface will be instantiated
|
||||
@@ -47,6 +48,7 @@ import org.diylc.core.annotations.EditableProperty;
|
||||
*
|
||||
* @param <T> type of component values, e.g. Resistance for resistors or String for transistors.
|
||||
*/
|
||||
@Indexed
|
||||
public interface IDIYComponent<T> extends Serializable, Cloneable {
|
||||
|
||||
public static final int CHASSIS = 1;
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.diylc.core.IDIYComponent;
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
@Indexed
|
||||
public interface IAutoCreator {
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
|
||||
This file is part of DIYLC.
|
||||
|
||||
DIYLC is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DIYLC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.core.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.diylc.utils.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Marks a type whose concrete implementations are discovered at runtime. The
|
||||
* {@code diylc-processor} annotation processor lists them under {@code META-INF/services} when
|
||||
* the implementing module is compiled, and {@link ReflectionUtils#getIndexedClasses(Class)} reads
|
||||
* that list back, so nothing has to scan the classpath. An implementation is picked up just by
|
||||
* implementing the type; there is no registry to update.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
@Retention(RetentionPolicy.CLASS)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface Indexed {
|
||||
|
||||
}
|
||||
@@ -2,6 +2,9 @@ package org.diylc.netlist;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.diylc.core.annotations.Indexed;
|
||||
|
||||
@Indexed
|
||||
public interface IGuitarDiagramAnalyzer {
|
||||
|
||||
List<String> collectNotes(Netlist netlist);
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.annotations.Indexed;
|
||||
|
||||
/*
|
||||
*
|
||||
@@ -41,6 +42,7 @@ import org.diylc.core.IDIYComponent;
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
@Indexed
|
||||
public interface INetlistParser {
|
||||
|
||||
String getName();
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2025 held jointly by the individual authors.
|
||||
|
||||
This file is part of DIYLC.
|
||||
|
||||
DIYLC is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
DIYLC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with DIYLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.diylc.core.IDIYComponent;
|
||||
|
||||
/**
|
||||
* Toolbox icon of a component type. Drawing it means instantiating the component, so it is
|
||||
* deferred until the icon is first painted rather than done for every type at startup.
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
class ComponentIcon implements Icon {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(ComponentIcon.class);
|
||||
|
||||
private final Class<? extends IDIYComponent<?>> componentClass;
|
||||
private BufferedImage image;
|
||||
|
||||
ComponentIcon(Class<? extends IDIYComponent<?>> componentClass) {
|
||||
this.componentClass = componentClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
if (image == null) {
|
||||
image = drawImage();
|
||||
}
|
||||
g.drawImage(image, x, y, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return Presenter.ICON_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return Presenter.ICON_SIZE;
|
||||
}
|
||||
|
||||
private BufferedImage drawImage() {
|
||||
BufferedImage image =
|
||||
new BufferedImage(Presenter.ICON_SIZE, Presenter.ICON_SIZE, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = image.createGraphics();
|
||||
try {
|
||||
IDIYComponent<?> componentInstance = componentClass.getDeclaredConstructor().newInstance();
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
|
||||
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
||||
componentInstance.drawIcon(g2d, Presenter.ICON_SIZE, Presenter.ICON_SIZE);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error drawing component icon for " + componentClass.getName(), e);
|
||||
} finally {
|
||||
g2d.dispose();
|
||||
}
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@@ -21,19 +21,13 @@
|
||||
*/
|
||||
package org.diylc.presenter;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import org.diylc.common.ComponentType;
|
||||
@@ -53,11 +47,7 @@ import org.diylc.core.annotations.EditableProperty;
|
||||
import org.diylc.core.annotations.KeywordPolicy;
|
||||
|
||||
import org.diylc.lang.LangUtil;
|
||||
import org.reflections.Reflections;
|
||||
import org.reflections.util.ConfigurationBuilder;
|
||||
import org.reflections.util.FilterBuilder;
|
||||
|
||||
import static org.reflections.scanners.Scanners.TypesAnnotated;
|
||||
import org.diylc.utils.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* Utility class with component processing methods.
|
||||
@@ -138,26 +128,7 @@ public class ComponentProcessor {
|
||||
} else { // default
|
||||
return null;
|
||||
}
|
||||
icon = null;
|
||||
// Draw component icon.
|
||||
try {
|
||||
IDIYComponent<?> componentInstance = (IDIYComponent<?>) clazz.getDeclaredConstructor().newInstance();
|
||||
Image image =
|
||||
new BufferedImage(Presenter.ICON_SIZE, Presenter.ICON_SIZE, java.awt.image.BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2d = (Graphics2D) image.getGraphics();
|
||||
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
|
||||
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
|
||||
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
|
||||
// g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
|
||||
// RenderingHints.VALUE_STROKE_PURE);
|
||||
componentInstance.drawIcon(g2d, Presenter.ICON_SIZE, Presenter.ICON_SIZE);
|
||||
icon = new ImageIcon(image);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error drawing component icon", e);
|
||||
}
|
||||
icon = new ComponentIcon(clazz);
|
||||
ComponentType componentType =
|
||||
new ComponentType(name, description, creationMethod, category, namePrefix, author, icon, clazz, zOrder,
|
||||
flexibleZOrder, bomPolicy, autoEdit, transformer, keywordPolicy, keywordTag, cacheDrawing, datasheet,
|
||||
@@ -254,64 +225,57 @@ public class ComponentProcessor {
|
||||
if (componentTypes == null) {
|
||||
LOG.info("Loading component types.");
|
||||
componentTypes = new HashMap<String, List<ComponentType>>();
|
||||
Reflections reflections = new Reflections(
|
||||
new ConfigurationBuilder()
|
||||
.forPackage("org.diylc")
|
||||
.filterInputsBy(new FilterBuilder().includePackage("org.diylc.components"))
|
||||
.setScanners(TypesAnnotated));
|
||||
Set<Class<?>> componentTypeClasses = null;
|
||||
try {
|
||||
componentTypeClasses = reflections.getTypesAnnotatedWith(ComponentDescriptor.class, false);
|
||||
List<Map<String, Object>> componentSnapshots = LOG_COMPONENT_TYPE_DETAILS ? new ArrayList<>() : null;
|
||||
|
||||
for (Class<?> clazz : componentTypeClasses) {
|
||||
if (!Modifier.isAbstract(clazz.getModifiers()) && IDIYComponent.class.isAssignableFrom(clazz)) {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) clazz);
|
||||
if (componentType == null)
|
||||
continue;
|
||||
for (Class<?> clazz : ReflectionUtils.getIndexedClasses(IDIYComponent.class)) {
|
||||
ComponentType componentType =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) clazz);
|
||||
if (componentType == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// just to store in the cache
|
||||
ComponentProcessor.getInstance().extractProperties(clazz);
|
||||
// just to store in the cache
|
||||
ComponentProcessor.getInstance().extractProperties(clazz);
|
||||
|
||||
// types created only programmatically (e.g. CompositeComponent) don't belong in the
|
||||
// palette, but still need to go through extractProperties() above so the cache is warm
|
||||
if (clazz.getAnnotation(ComponentDescriptor.class).hiddenInPalette())
|
||||
continue;
|
||||
// types created only programmatically (e.g. CompositeComponent) don't belong in the
|
||||
// palette, but still need to go through extractProperties() above so the cache is warm
|
||||
if (clazz.getAnnotation(ComponentDescriptor.class).hiddenInPalette()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<ComponentType> nestedList;
|
||||
if (componentTypes.containsKey(componentType.getCategory())) {
|
||||
nestedList = componentTypes.get(componentType.getCategory());
|
||||
} else {
|
||||
nestedList = new ArrayList<ComponentType>();
|
||||
componentTypes.put(componentType.getCategory(), nestedList);
|
||||
}
|
||||
nestedList.add(componentType);
|
||||
List<ComponentType> nestedList;
|
||||
if (componentTypes.containsKey(componentType.getCategory())) {
|
||||
nestedList = componentTypes.get(componentType.getCategory());
|
||||
} else {
|
||||
nestedList = new ArrayList<ComponentType>();
|
||||
componentTypes.put(componentType.getCategory(), nestedList);
|
||||
}
|
||||
nestedList.add(componentType);
|
||||
|
||||
if (LOG_COMPONENT_TYPE_DETAILS) {
|
||||
try {
|
||||
Map<String, Object> snapshot = new LinkedHashMap<>();
|
||||
snapshot.put("name", componentType.getName());
|
||||
snapshot.put("description", componentType.getDescription());
|
||||
snapshot.put("creationMethod", componentType.getCreationMethod());
|
||||
snapshot.put("category", componentType.getCategory());
|
||||
List<PropertyWrapper> props = propertyCache.get(clazz.getName());
|
||||
snapshot.put("properties", props != null ? props.stream()
|
||||
.map(p -> {
|
||||
Map<String, Object> prop = new LinkedHashMap<>();
|
||||
prop.put("name", p.getName());
|
||||
prop.put("type", formatPropertyType(p.getType()));
|
||||
List<String> possibleValues = getPossibleValues(p.getType());
|
||||
if (possibleValues != null) {
|
||||
prop.put("possibleValues", possibleValues);
|
||||
}
|
||||
return prop;
|
||||
})
|
||||
.collect(Collectors.toList()) : Collections.emptyList());
|
||||
componentSnapshots.add(snapshot);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Failed to log component type details for " + clazz.getName(), e);
|
||||
}
|
||||
if (LOG_COMPONENT_TYPE_DETAILS) {
|
||||
try {
|
||||
Map<String, Object> snapshot = new LinkedHashMap<>();
|
||||
snapshot.put("name", componentType.getName());
|
||||
snapshot.put("description", componentType.getDescription());
|
||||
snapshot.put("creationMethod", componentType.getCreationMethod());
|
||||
snapshot.put("category", componentType.getCategory());
|
||||
List<PropertyWrapper> props = propertyCache.get(clazz.getName());
|
||||
snapshot.put("properties", props != null ? props.stream()
|
||||
.map(p -> {
|
||||
Map<String, Object> prop = new LinkedHashMap<>();
|
||||
prop.put("name", p.getName());
|
||||
prop.put("type", formatPropertyType(p.getType()));
|
||||
List<String> possibleValues = getPossibleValues(p.getType());
|
||||
if (possibleValues != null) {
|
||||
prop.put("possibleValues", possibleValues);
|
||||
}
|
||||
return prop;
|
||||
})
|
||||
.collect(Collectors.toList()) : Collections.emptyList());
|
||||
componentSnapshots.add(snapshot);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Failed to log component type details for " + clazz.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,6 @@ import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
@@ -3133,16 +3132,8 @@ public class Presenter implements IPlugInPort {
|
||||
|
||||
@Override
|
||||
public List<INetlistAnalyzer> getNetlistAnalyzers() {
|
||||
Set<Class<?>> classes;
|
||||
try {
|
||||
classes = Utils.getClasses("org.diylc.netlist");
|
||||
List<INetlistAnalyzer> result = new ArrayList<INetlistAnalyzer>();
|
||||
|
||||
for (Class<?> clazz : classes) {
|
||||
if (!Modifier.isAbstract(clazz.getModifiers()) && INetlistAnalyzer.class.isAssignableFrom(clazz)) {
|
||||
result.add((INetlistAnalyzer) clazz.getDeclaredConstructor().newInstance());
|
||||
}
|
||||
}
|
||||
List<INetlistAnalyzer> result = ReflectionUtils.getIndexedInstances(INetlistAnalyzer.class);
|
||||
|
||||
result.sort(new Comparator<INetlistAnalyzer>() {
|
||||
|
||||
|
||||
@@ -26,7 +26,9 @@ import java.util.List;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.annotations.Indexed;
|
||||
|
||||
@Indexed
|
||||
public interface IOldFileParser {
|
||||
|
||||
boolean canParse(String version);
|
||||
|
||||
@@ -30,7 +30,6 @@ import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
@@ -41,7 +40,6 @@ import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.appframework.miscutils.Utils;
|
||||
import org.diylc.appframework.simplemq.MessageDispatcher;
|
||||
import org.diylc.appframework.update.VersionNumber;
|
||||
import org.w3c.dom.Document;
|
||||
@@ -59,6 +57,7 @@ import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.presenter.Presenter;
|
||||
import org.diylc.test.DIYTest;
|
||||
import org.diylc.utils.ReflectionUtils;
|
||||
|
||||
public class ProjectFileManager {
|
||||
|
||||
@@ -144,17 +143,10 @@ public class ProjectFileManager {
|
||||
|
||||
public List<IOldFileParser> getParsers() {
|
||||
if (parsers == null) {
|
||||
parsers = new ArrayList<IOldFileParser>();
|
||||
Set<Class<?>> componentTypeClasses = null;
|
||||
try {
|
||||
componentTypeClasses = Utils.getClasses("org.diylc.serialization");
|
||||
for (Class<?> clazz : componentTypeClasses) {
|
||||
if (!Modifier.isAbstract(clazz.getModifiers()) && IOldFileParser.class.isAssignableFrom(clazz)) {
|
||||
IOldFileParser instance = (IOldFileParser) clazz.getDeclaredConstructor().newInstance();
|
||||
parsers.add(instance);
|
||||
}
|
||||
}
|
||||
parsers = ReflectionUtils.getIndexedInstances(IOldFileParser.class);
|
||||
} catch (Exception e) {
|
||||
parsers = new ArrayList<IOldFileParser>();
|
||||
LOG.error("Could not find old version parsers", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,23 +21,30 @@
|
||||
*/
|
||||
package org.diylc.utils;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.appframework.miscutils.Utils;
|
||||
|
||||
import org.diylc.core.annotations.IAutoCreator;
|
||||
import org.diylc.core.annotations.Indexed;
|
||||
import org.diylc.netlist.IGuitarDiagramAnalyzer;
|
||||
import org.diylc.netlist.INetlistParser;
|
||||
import org.diylc.presenter.Presenter;
|
||||
|
||||
public class ReflectionUtils {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(Presenter.class);
|
||||
private static final Logger LOG = Logger.getLogger(ReflectionUtils.class);
|
||||
|
||||
private static final String SERVICES_DIR = "META-INF/services/";
|
||||
|
||||
/**
|
||||
* {@link List} of {@link IAutoCreator} objects that are capable of creating more components
|
||||
@@ -45,19 +52,66 @@ public class ReflectionUtils {
|
||||
*/
|
||||
private static List<IAutoCreator> autoCreators;
|
||||
|
||||
public static List<IAutoCreator> getAutoCreators() {
|
||||
if (autoCreators == null) {
|
||||
autoCreators = new ArrayList<IAutoCreator>();
|
||||
Set<Class<?>> classes = null;
|
||||
try {
|
||||
classes = Utils.getClasses("org.diylc.components.autocreate");
|
||||
for (Class<?> clazz : classes) {
|
||||
if (IAutoCreator.class.isAssignableFrom(clazz)) {
|
||||
autoCreators.add((IAutoCreator) clazz.getDeclaredConstructor().newInstance());
|
||||
LOG.debug("Loaded auto-creator: " + clazz.getName());
|
||||
/**
|
||||
* Returns the concrete implementations of an {@link Indexed} type, as listed at build time by
|
||||
* {@code diylc-processor}. Classes are loaded but not initialized.
|
||||
*/
|
||||
public static <T> List<Class<? extends T>> getIndexedClasses(Class<T> type) {
|
||||
ClassLoader classLoader = ReflectionUtils.class.getClassLoader();
|
||||
// each module jar carries its own index file for the same type
|
||||
Set<String> classNames = new LinkedHashSet<String>();
|
||||
try {
|
||||
Enumeration<URL> indexFiles = classLoader.getResources(SERVICES_DIR + type.getName());
|
||||
while (indexFiles.hasMoreElements()) {
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(indexFiles.nextElement().openStream(), StandardCharsets.UTF_8))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
line = line.trim();
|
||||
if (!line.isEmpty() && !line.startsWith("#")) {
|
||||
classNames.add(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOG.error("Could not read the class index of " + type.getName(), e);
|
||||
}
|
||||
|
||||
List<Class<? extends T>> result = new ArrayList<Class<? extends T>>(classNames.size());
|
||||
for (String className : classNames) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName(className, false, classLoader);
|
||||
if (type.isAssignableFrom(clazz)) {
|
||||
result.add(clazz.asSubclass(type));
|
||||
} else {
|
||||
LOG.warn("Class index of " + type.getName() + " lists unrelated class " + className);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOG.warn("Class index of " + type.getName() + " lists missing class " + className);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates every class returned by {@link #getIndexedClasses(Class)} through its no-arg
|
||||
* constructor.
|
||||
*/
|
||||
public static <T> List<T> getIndexedInstances(Class<T> type) throws ReflectiveOperationException {
|
||||
List<T> result = new ArrayList<T>();
|
||||
for (Class<? extends T> clazz : getIndexedClasses(type)) {
|
||||
result.add(clazz.getDeclaredConstructor().newInstance());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<IAutoCreator> getAutoCreators() {
|
||||
if (autoCreators == null) {
|
||||
try {
|
||||
autoCreators = getIndexedInstances(IAutoCreator.class);
|
||||
} catch (Exception e) {
|
||||
autoCreators = new ArrayList<IAutoCreator>();
|
||||
LOG.error("Error loading auto-creator types", e);
|
||||
}
|
||||
}
|
||||
@@ -65,16 +119,8 @@ public class ReflectionUtils {
|
||||
}
|
||||
|
||||
public static List<INetlistParser> getNetlistParserDefinitions() {
|
||||
Set<Class<?>> classes;
|
||||
try {
|
||||
classes = Utils.getClasses("org.diylc.netlist");
|
||||
List<INetlistParser> result = new ArrayList<INetlistParser>();
|
||||
|
||||
for (Class<?> clazz : classes) {
|
||||
if (!Modifier.isAbstract(clazz.getModifiers()) && INetlistParser.class.isAssignableFrom(clazz)) {
|
||||
result.add((INetlistParser) clazz.getDeclaredConstructor().newInstance());
|
||||
}
|
||||
}
|
||||
List<INetlistParser> result = getIndexedInstances(INetlistParser.class);
|
||||
|
||||
Collections.sort(result, new Comparator<INetlistParser>() {
|
||||
|
||||
@@ -92,16 +138,7 @@ public class ReflectionUtils {
|
||||
}
|
||||
|
||||
public static IGuitarDiagramAnalyzer getGuitarDiagramAnalyzer() throws Exception {
|
||||
Set<Class<?>> classes;
|
||||
classes = Utils.getClasses("org.diylc.netlist");
|
||||
List<IGuitarDiagramAnalyzer> result = new ArrayList<>();
|
||||
|
||||
for (Class<?> clazz : classes) {
|
||||
if (!Modifier.isAbstract(clazz.getModifiers()) && IGuitarDiagramAnalyzer.class.isAssignableFrom(clazz)) {
|
||||
result.add((IGuitarDiagramAnalyzer) clazz.getDeclaredConstructor().newInstance());
|
||||
}
|
||||
}
|
||||
|
||||
List<IGuitarDiagramAnalyzer> result = getIndexedInstances(IGuitarDiagramAnalyzer.class);
|
||||
|
||||
if (result.isEmpty()) {
|
||||
return null;
|
||||
|
||||
@@ -611,7 +611,11 @@
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improve performance of 'Project Explorer' pane</description>
|
||||
<description>Improved performance of application initialization</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>IMPROVEMENT</changeType>
|
||||
<description>Improved performance of 'Project Explorer' pane</description>
|
||||
</org.diylc.appframework.update.Change>
|
||||
<org.diylc.appframework.update.Change>
|
||||
<changeType>BUG_FIX</changeType>
|
||||
|
||||
Reference in New Issue
Block a user