mirror of
https://github.com/bancika/diy-layout-creator
synced 2026-11-07 12:24:58 +10:00
Cleanup code, refactor presenter
This commit is contained in:
@@ -313,13 +313,6 @@ public interface IPlugInPort extends ISelectionProcessor, IMouseProcessor, IKeyP
|
||||
*/
|
||||
void setNewComponentTypeSlot(ComponentType componentType, Template template, boolean forceInstatiate);
|
||||
|
||||
/**
|
||||
* Changes default size notation, true for metric, false for imperial.
|
||||
*
|
||||
* @param isMetric
|
||||
*/
|
||||
void setMetric(boolean isMetric);
|
||||
|
||||
/**
|
||||
* Locks or unlocks the specified layer. All components within +- 0.5 range will be affected by
|
||||
* the change as well.
|
||||
|
||||
@@ -51,15 +51,6 @@ public abstract class NetlistAnalyzer {
|
||||
Tree tree = new Tree(TreeConnectionType.Parallel);
|
||||
connectNodes(netlist, nodeA, nodeB, tree.getChildren(), new Tree(TreeConnectionType.Series), new HashSet<Node>());
|
||||
|
||||
// System.out.println(netlist.getSwitchSetup());
|
||||
// System.out.println(tree);
|
||||
//
|
||||
// System.out.println("opposite:");
|
||||
// Tree tree1 = new Tree(TreeConnectionType.Parallel);
|
||||
// connectNodes(netlist, nodeB, nodeA, tree1.getChildren(), new Tree(TreeConnectionType.Series),
|
||||
// new HashSet<Node>());
|
||||
// System.out.println(tree1);
|
||||
|
||||
return tree;
|
||||
}
|
||||
|
||||
@@ -112,7 +103,6 @@ public abstract class NetlistAnalyzer {
|
||||
if (newConcurrentPaths.size() == 0)
|
||||
return;
|
||||
|
||||
|
||||
if (newConcurrentPaths.size() == 1) {
|
||||
if (newConcurrentPaths.get(0).getConnectionType() == TreeConnectionType.Series) {
|
||||
currentPath.getChildren().clear();
|
||||
@@ -214,45 +204,6 @@ public abstract class NetlistAnalyzer {
|
||||
paths.addAll(unmerged);
|
||||
}
|
||||
}
|
||||
//
|
||||
// protected void findAllPaths(Netlist netlist, Node nodeA, Node nodeB, List<TreeLeaf> currentPath,
|
||||
// List<List<TreeLeaf>> allPaths, Set<Node> visited) {
|
||||
// if (nodeA == nodeB) {
|
||||
// allPaths.add(currentPath);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // System.out.println("Finding path between " + nodeA + " and " + nodeB);
|
||||
//
|
||||
// Group groupA = findGroup(netlist, nodeA);
|
||||
//
|
||||
// if (groupA == null)
|
||||
// return;
|
||||
//
|
||||
// if (groupA.getNodes().contains(nodeB)) {
|
||||
// allPaths.add(currentPath);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// for (Node n : groupA.getNodes()) {
|
||||
// IDIYComponent<?> c = n.getComponent();
|
||||
// for (int i = 0; i < c.getControlPointCount(); i++) {
|
||||
// if (i != n.getPointIndex() && c.getInternalLinkName(i, n.getPointIndex()) != null) {
|
||||
// TreeLeaf l = new TreeLeaf(c, i, n.getPointIndex());
|
||||
// Node newNodeA = new Node(c, i);
|
||||
// if (!visited.contains(newNodeA)) {
|
||||
// List<TreeLeaf> newCurrentPath = new ArrayList<TreeLeaf>(currentPath);
|
||||
// if (!currentPath.contains(l))
|
||||
// newCurrentPath.add(l);
|
||||
// Set<Node> newVisited = new HashSet<Node>(visited);
|
||||
// newVisited.add(nodeA);
|
||||
// newVisited.add(newNodeA);
|
||||
// findAllPaths(netlist, newNodeA, nodeB, newCurrentPath, allPaths, newVisited);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
protected Group findGroup(Netlist netlist, Node node) {
|
||||
for (Group g : netlist.getGroups())
|
||||
@@ -261,63 +212,6 @@ public abstract class NetlistAnalyzer {
|
||||
return null;
|
||||
}
|
||||
|
||||
// protected List<Group> trace(Set<String> typeNames, String nodeName, Netlist netlist) {
|
||||
// List<Group> res = new ArrayList<Group>();
|
||||
// for (Group g : netlist.getGroups()) {
|
||||
// for (Node n : g.getNodes()) {
|
||||
// if (typeNames.contains(n.getComponent().getClass().getCanonicalName())
|
||||
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
|
||||
// res.add(g);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// protected List<Node> find(Set<String> typeNames, String nodeName, Group group) {
|
||||
// List<Node> res = new ArrayList<Node>();
|
||||
//
|
||||
// for (Node n : group.getNodes()) {
|
||||
// if (typeNames.contains(n.getComponent().getClass().getCanonicalName())
|
||||
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
|
||||
// res.add(n);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// protected List<Group> findGroups(Set<String> typeNames, String nodeName, Netlist netlist) {
|
||||
// List<Group> res = new ArrayList<Group>();
|
||||
// for (Group g : netlist.getGroups()) {
|
||||
// for (Node n : g.getNodes()) {
|
||||
// if (typeNames.contains(n.getComponent().getClass().getCanonicalName())
|
||||
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
|
||||
// res.add(g);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// protected List<Group> findGroups(Set<String> typeNames, String nodeName, Netlist netlist,
|
||||
// Collection<IDIYComponent<?>> belongTo) {
|
||||
// List<Group> res = new ArrayList<Group>();
|
||||
// for (Group g : netlist.getGroups()) {
|
||||
// for (Node n : g.getNodes()) {
|
||||
// if ((belongTo == null || belongTo.contains(n.getComponent()))
|
||||
// && (typeNames.contains(n.getComponent().getClass().getCanonicalName()))
|
||||
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
|
||||
// res.add(g);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return res;
|
||||
// }
|
||||
|
||||
protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist) {
|
||||
List<Node> res = new ArrayList<Node>();
|
||||
for (Group g : netlist.getGroups()) {
|
||||
@@ -331,68 +225,6 @@ public abstract class NetlistAnalyzer {
|
||||
return res;
|
||||
}
|
||||
|
||||
// protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist, List<Node> inGroupWith) {
|
||||
// List<Node> res = new ArrayList<Node>();
|
||||
// for (Group g : netlist.getGroups()) {
|
||||
//
|
||||
// boolean inGroup;
|
||||
// if (inGroupWith == null) {
|
||||
// inGroup = true;
|
||||
// } else {
|
||||
// inGroup = true;
|
||||
// for (Node n1 : inGroupWith)
|
||||
// if (!g.getNodes().contains(n1)) {
|
||||
// inGroup = false;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (Node n : g.getNodes()) {
|
||||
// if (inGroup && typeNames.contains(n.getComponent().getClass().getCanonicalName())
|
||||
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
|
||||
// res.add(n);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// protected List<Node> find(Set<String> typeNames, String nodeName, Netlist netlist,
|
||||
// Collection<IDIYComponent<?>> belongTo) {
|
||||
// List<Node> res = new ArrayList<Node>();
|
||||
// for (Group g : netlist.getGroups()) {
|
||||
//
|
||||
// for (Node n : g.getNodes()) {
|
||||
// if ((belongTo == null || belongTo.contains(n.getComponent()))
|
||||
// && typeNames.contains(n.getComponent().getClass().getCanonicalName())
|
||||
// && (nodeName == null || n.getDisplayName().equalsIgnoreCase(nodeName))) {
|
||||
// res.add(n);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return res;
|
||||
// }
|
||||
|
||||
// protected boolean allMatch(Collection<Node> nodes, String name) {
|
||||
// for (Node n : nodes)
|
||||
// if (!n.getDisplayName().equalsIgnoreCase(name))
|
||||
// return false;
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// protected boolean allComponentsMatch(Collection<Node> nodes, Set<IDIYComponent<?>> components) {
|
||||
// Set<IDIYComponent<?>> extracted = extractComponents(nodes);
|
||||
// return extracted.containsAll(components);
|
||||
// }
|
||||
//
|
||||
// protected Set<IDIYComponent<?>> extractComponents(Collection<Node> nodes) {
|
||||
// Set<IDIYComponent<?>> components = new HashSet<IDIYComponent<?>>();
|
||||
// for (Node n : nodes)
|
||||
// components.add(n.getComponent());
|
||||
// return components;
|
||||
// }
|
||||
|
||||
protected String extractName(IDIYComponent<?> c) {
|
||||
return c.getName() + " " + c.getValueForDisplay();
|
||||
}
|
||||
@@ -423,53 +255,6 @@ public abstract class NetlistAnalyzer {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// protected List<String> extractNames(Collection<IDIYComponent<?>> components) {
|
||||
// List<String> names = new ArrayList<String>();
|
||||
// for (IDIYComponent<?> c : components)
|
||||
// names.add(c.getName() + " " + c.getValueForDisplay());
|
||||
// Collections.sort(names);
|
||||
// return names;
|
||||
// }
|
||||
//
|
||||
// protected Netlist simplify(Netlist netlist, Set<Node> nodesToMerge, Collection<Node> nodesToPurge) {
|
||||
// Netlist res = new Netlist();
|
||||
// res.getSwitchSetup().addAll(netlist.getSwitchSetup());
|
||||
//
|
||||
// Group merged = new Group();
|
||||
//
|
||||
// // merge
|
||||
// for (Group g : netlist.getGroups()) {
|
||||
// boolean needsMerging = false;
|
||||
// for (Node n : nodesToMerge) {
|
||||
// if (g.getNodes().contains(n)) {
|
||||
// needsMerging = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// if (needsMerging) {
|
||||
// for (Node n : g.getNodes()) {
|
||||
// if (!nodesToMerge.contains(n))
|
||||
// merged.getNodes().add(n);
|
||||
// }
|
||||
// } else {
|
||||
// res.getGroups().add(g.clone());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!merged.getNodes().isEmpty())
|
||||
// res.getGroups().add(merged);
|
||||
//
|
||||
// // purge
|
||||
// for (Group g : res.getGroups()) {
|
||||
// g.getNodes().removeAll(nodesToPurge);
|
||||
// }
|
||||
//
|
||||
// System.out.println("Before:\n" + netlist);
|
||||
// System.out.println("After:\n" + res);
|
||||
//
|
||||
// return res;
|
||||
// }
|
||||
//
|
||||
protected boolean intersect(List<Group> groups, Node node) {
|
||||
for (Group g : groups)
|
||||
if (g.getNodes().contains(node))
|
||||
|
||||
@@ -21,14 +21,22 @@ import java.awt.geom.Area;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.stream.Collectors;
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.core.IContinuity;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.ISwitch;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.lang.LangUtil;
|
||||
import org.diylc.netlist.ContinuityGraph.ContinuityNode;
|
||||
import org.diylc.presenter.ComponentProcessor;
|
||||
import org.diylc.presenter.Connection;
|
||||
import org.diylc.utils.RTree;
|
||||
import com.google.common.graph.GraphBuilder;
|
||||
@@ -40,6 +48,121 @@ public class NetlistBuilder {
|
||||
|
||||
public static final float eps = 4; // consider any nodes closer than this as connected
|
||||
|
||||
private static final int MAX_SWITCH_COMBINATIONS = 64;
|
||||
|
||||
private static final String MAX_SWITCH_COMBINATIONS_ERROR = LangUtil
|
||||
.translate("Maximum number of switching combinations exceeded. Allowed: %s, actual: %s");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<Netlist> extractNetlists(boolean includeSwitches, Project project, List<Area> continuityAreas)
|
||||
throws NetlistException {
|
||||
Map<Netlist, Netlist> result = new HashMap<Netlist, Netlist>();
|
||||
List<Node> nodes = new ArrayList<Node>();
|
||||
|
||||
List<ISwitch> switches = new ArrayList<ISwitch>();
|
||||
|
||||
for (IDIYComponent<?> c : project.getComponents()) {
|
||||
ComponentType type = ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) c.getClass());
|
||||
|
||||
// extract nodes
|
||||
if (!(c instanceof IContinuity)) {
|
||||
for (int i = 0; i < c.getControlPointCount(); i++) {
|
||||
String nodeName = c.getControlPointNodeName(i);
|
||||
if (nodeName != null
|
||||
&& (!includeSwitches || !ISwitch.class.isAssignableFrom(type.getInstanceClass()))) {
|
||||
nodes.add(new Node(c, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// extract switches
|
||||
if (includeSwitches && ISwitch.class.isAssignableFrom(type.getInstanceClass()))
|
||||
switches.add((ISwitch) c);
|
||||
}
|
||||
|
||||
// save us the trouble
|
||||
if (nodes.isEmpty())
|
||||
return null;
|
||||
|
||||
// if there are no switches, make one with 1 position so we get 1 result back
|
||||
if (switches.isEmpty())
|
||||
switches.add(new ISwitch() {
|
||||
|
||||
@Override
|
||||
public String getPositionName(int position) {
|
||||
return "Default";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPositionCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean arePointsConnected(int index1, int index2, int position) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// construct all possible combinations
|
||||
int[] positions = new int[switches.size()];
|
||||
for (int i = 0; i < switches.size(); i++)
|
||||
positions[i] = 0;
|
||||
|
||||
int i = switches.size() - 1;
|
||||
|
||||
int totalSwitchCombinations =
|
||||
switches.stream().map(sw -> sw.getPositionCount()).reduce(1, (a, b) -> a * b);
|
||||
|
||||
if (totalSwitchCombinations > MAX_SWITCH_COMBINATIONS) {
|
||||
throw new NetlistException(String.format(MAX_SWITCH_COMBINATIONS_ERROR,
|
||||
MAX_SWITCH_COMBINATIONS, totalSwitchCombinations));
|
||||
}
|
||||
|
||||
while (i >= 0) {
|
||||
// process the current combination
|
||||
Map<ISwitch, Integer> switchPositions = new HashMap<ISwitch, Integer>();
|
||||
List<Position> posList = new ArrayList<Position>();
|
||||
for (int j = 0; j < positions.length; j++) {
|
||||
switchPositions.put(switches.get(j), positions[j]);
|
||||
posList.add(new Position(switches.get(j), positions[j]));
|
||||
}
|
||||
List<Connection> connections = getConnections(project, switchPositions);
|
||||
|
||||
Netlist netlist = NetlistBuilder.buildNetlist(project.getComponents(), nodes,
|
||||
continuityAreas, connections);
|
||||
|
||||
// merge graphs that are effectively the same
|
||||
if (result.containsKey(netlist)) {
|
||||
result.get(netlist).getSwitchSetup().add(new SwitchSetup(posList));
|
||||
} else {
|
||||
netlist.getSwitchSetup().add(new SwitchSetup(posList));
|
||||
result.put(netlist, netlist);
|
||||
}
|
||||
|
||||
// find the next combination if possible
|
||||
if (positions[i] < switches.get(i).getPositionCount() - 1) {
|
||||
positions[i]++;
|
||||
} else {
|
||||
while (i >= 0 && positions[i] == switches.get(i).getPositionCount() - 1)
|
||||
i--;
|
||||
if (i >= 0) {
|
||||
positions[i]++;
|
||||
for (int j = i + 1; j < positions.length; j++)
|
||||
positions[j] = 0;
|
||||
i = switches.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort everything alphabetically
|
||||
List<Netlist> netlists = new ArrayList<Netlist>(result.keySet());
|
||||
Collections.sort(netlists);
|
||||
|
||||
return netlists;
|
||||
}
|
||||
|
||||
public static Netlist buildNetlist(List<IDIYComponent<?>> components, Collection<Node> nodes,
|
||||
Collection<Area> continuityAreas, Collection<Connection> connections) {
|
||||
ImmutableGraph<ProjectGraphNode> graph = buildGraph(nodes, continuityAreas, connections);
|
||||
@@ -75,17 +198,19 @@ public class NetlistBuilder {
|
||||
|
||||
return netlist;
|
||||
}
|
||||
|
||||
public static ContinuityGraph buildContinuityGraph(Collection<Area> continuityAreas, Collection<Connection> connections) {
|
||||
ImmutableGraph<ProjectGraphNode> graph = buildGraph(new ArrayList<Node>(), continuityAreas, connections);
|
||||
|
||||
public static ContinuityGraph buildContinuityGraph(Collection<Area> continuityAreas,
|
||||
Collection<Connection> connections) {
|
||||
ImmutableGraph<ProjectGraphNode> graph =
|
||||
buildGraph(new ArrayList<Node>(), continuityAreas, connections);
|
||||
|
||||
Traverser<ProjectGraphNode> traverser = Traverser.forGraph(graph);
|
||||
Set<ProjectGraphNode> visited = new HashSet<ProjectGraphNode>();
|
||||
|
||||
ProjectGraphNode[] nodeArr = graph.nodes().toArray(new ProjectGraphNode[0]);
|
||||
|
||||
|
||||
int groupId = 1;
|
||||
|
||||
|
||||
RTree<ContinuityNode> groupTree = new RTree<ContinuityGraph.ContinuityNode>();
|
||||
Map<Integer, List<Area>> areaGroupMap = new HashMap<Integer, List<Area>>();
|
||||
|
||||
@@ -97,7 +222,7 @@ public class NetlistBuilder {
|
||||
|
||||
if (i == graph.nodes().size())
|
||||
break;
|
||||
|
||||
|
||||
final int finalGroupId = groupId;
|
||||
|
||||
List<Area> areaList = new ArrayList<Area>();
|
||||
@@ -178,7 +303,7 @@ public class NetlistBuilder {
|
||||
|
||||
for (Area area : continuityAreas) {
|
||||
ProjectGraphNode areaNode = new ProjectGraphNode(area);
|
||||
builder.addNode(areaNode);
|
||||
builder.addNode(areaNode);
|
||||
|
||||
ProjectGraphNode[] nodeArr = nodeTree.search(area).stream()
|
||||
.filter(graphNode -> area.contains(graphNode.getPoint())
|
||||
@@ -206,11 +331,39 @@ public class NetlistBuilder {
|
||||
}).forEach(graphNode -> {
|
||||
builder.putEdge(graphNode, areaNode);
|
||||
});
|
||||
|
||||
|
||||
areaTree.insert(area, areaNode);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "unlikely-arg-type"})
|
||||
private static List<Connection> getConnections(Project project, Map<ISwitch, Integer> switchPositions) {
|
||||
Set<Connection> connections = new TreeSet<Connection>();
|
||||
|
||||
for (IDIYComponent<?> c : project.getComponents()) {
|
||||
ComponentType type =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) c.getClass());
|
||||
// handle direct connections
|
||||
if (c instanceof IContinuity) {
|
||||
for (int i = 0; i < c.getControlPointCount() - 1; i++)
|
||||
for (int j = i + 1; j < c.getControlPointCount(); j++)
|
||||
if (((IContinuity) c).arePointsConnected(i, j))
|
||||
connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j)));
|
||||
}
|
||||
// handle switches
|
||||
if (ISwitch.class.isAssignableFrom(type.getInstanceClass()) && switchPositions.containsKey(c)) {
|
||||
int position = switchPositions.get(c);
|
||||
ISwitch s = (ISwitch) c;
|
||||
for (int i = 0; i < c.getControlPointCount() - 1; i++)
|
||||
for (int j = i + 1; j < c.getControlPointCount(); j++)
|
||||
if (s.arePointsConnected(i, j, position))
|
||||
connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j)));
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<Connection>(connections);
|
||||
}
|
||||
|
||||
private static Point2D snapToEps(Point2D point, double eps) {
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
*
|
||||
* l * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 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.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.appframework.miscutils.IConfigurationManager;
|
||||
import org.diylc.common.BuildingBlockPackage;
|
||||
import org.diylc.common.IBlockProcessor;
|
||||
import org.diylc.common.IBlockProcessor.InvalidBlockException;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.serialization.ProjectFileManager;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.io.xml.DomDriver;
|
||||
import com.thoughtworks.xstream.security.AnyTypePermission;
|
||||
|
||||
public class BuildingBlockManager {
|
||||
|
||||
private static final String BLOCKS_FILE_NAME = "blocks.xml";
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(VariantManager.class);
|
||||
|
||||
private IConfigurationManager<?> configManager;
|
||||
private XStream xStream;
|
||||
private InstantiationManager instantiationManager;
|
||||
|
||||
public BuildingBlockManager(IConfigurationManager<?> configManager, XStream xStream,
|
||||
InstantiationManager instantiationManager) {
|
||||
super();
|
||||
this.configManager = configManager;
|
||||
this.xStream = xStream;
|
||||
this.instantiationManager = instantiationManager;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void importDefaultBlocks() {
|
||||
// import default templates from variants.xml file only if we didn't do it already
|
||||
if (!configManager.readBoolean(IPlugInPort.DEFAULT_BLOCKS_IMPORTED_KEY, false)) {
|
||||
try {
|
||||
URL resource = Presenter.class.getResource(BLOCKS_FILE_NAME);
|
||||
if (resource != null) {
|
||||
BufferedInputStream in = new BufferedInputStream(resource.openStream());
|
||||
Map<String, List<IDIYComponent<?>>> defaults =
|
||||
(Map<String, List<IDIYComponent<?>>>) ProjectFileManager.xStreamSerializer
|
||||
.fromXML(in);
|
||||
in.close();
|
||||
|
||||
Map<String, List<IDIYComponent<?>>> blocksMap =
|
||||
(Map<String, List<IDIYComponent<?>>>) configManager.readObject(IPlugInPort.BLOCKS_KEY,
|
||||
null);
|
||||
if (blocksMap == null)
|
||||
blocksMap = new HashMap<String, List<IDIYComponent<?>>>();
|
||||
|
||||
// merge default blocks with user's
|
||||
for (Map.Entry<String, List<IDIYComponent<?>>> entry : defaults.entrySet()) {
|
||||
if (!blocksMap.containsKey(entry.getKey()))
|
||||
blocksMap.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
// update templates and a flag marking that we imported them
|
||||
configManager.writeValue(IPlugInPort.DEFAULT_BLOCKS_IMPORTED_KEY, true);
|
||||
configManager.writeValue(IPlugInPort.BLOCKS_KEY, blocksMap);
|
||||
LOG.info(String.format("Imported %d default building blocks",
|
||||
defaults == null ? 0 : defaults.size()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not load default blocks", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public int importBlocks(String fileName) throws IOException {
|
||||
LOG.debug(String.format("importBlocks(%s)", fileName));
|
||||
BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileName));
|
||||
|
||||
BuildingBlockPackage pkg = (BuildingBlockPackage) xStream.fromXML(in);
|
||||
|
||||
in.close();
|
||||
|
||||
if (pkg == null || pkg.getBlocks().isEmpty())
|
||||
return 0;
|
||||
|
||||
Map<String, List<IDIYComponent<?>>> blocks =
|
||||
(Map<String, List<IDIYComponent<?>>>) configManager.readObject(IBlockProcessor.BLOCKS_KEY, null);
|
||||
if (blocks == null) {
|
||||
blocks = new HashMap<String, List<IDIYComponent<?>>>();
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<IDIYComponent<?>>> entry : pkg.getBlocks().entrySet()) {
|
||||
blocks.put(entry.getKey() + " [" + pkg.getOwner() + "]", entry.getValue());
|
||||
}
|
||||
|
||||
configManager.writeValue(IBlockProcessor.BLOCKS_KEY, blocks);
|
||||
|
||||
LOG.info(String.format("Loaded building blocks for %d components", pkg.getBlocks().size()));
|
||||
|
||||
return pkg.getBlocks().size();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<IDIYComponent<?>> loadBlock(String blockName,
|
||||
List<IDIYComponent<?>> existingComponents) throws InvalidBlockException {
|
||||
LOG.debug(String.format("loadBlock(%s)", blockName));
|
||||
Map<String, List<IDIYComponent<?>>> blocks = (Map<String, List<IDIYComponent<?>>>) configManager
|
||||
.readObject(IPlugInPort.BLOCKS_KEY, null);
|
||||
if (blocks != null) {
|
||||
Collection<IDIYComponent<?>> components = blocks.get(blockName);
|
||||
if (components == null)
|
||||
throw new InvalidBlockException();
|
||||
// clear potential control point every time!
|
||||
instantiationManager.setPotentialControlPoint(null);
|
||||
// clone components
|
||||
List<IDIYComponent<?>> clones = new ArrayList<IDIYComponent<?>>();
|
||||
List<IDIYComponent<?>> testComponents = new ArrayList<IDIYComponent<?>>(existingComponents);
|
||||
for (IDIYComponent<?> c : components)
|
||||
try {
|
||||
IDIYComponent<?> clone = c.clone();
|
||||
clone.setName(instantiationManager.createUniqueName(ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) clone.getClass()),
|
||||
testComponents));
|
||||
testComponents.add(clone);
|
||||
clones.add(clone);
|
||||
} catch (CloneNotSupportedException e) {
|
||||
LOG.error("Could not clone component: " + c);
|
||||
}
|
||||
return clones;
|
||||
} else
|
||||
throw new InvalidBlockException();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void saveSelectionAsBlock(String blockName,
|
||||
Collection<IDIYComponent<?>> selectedComponents, List<IDIYComponent<?>> allComponents) {
|
||||
LOG.debug(String.format("saveSelectionAsBlock(%s)", blockName));
|
||||
Map<String, List<IDIYComponent<?>>> blocks = (Map<String, List<IDIYComponent<?>>>) configManager
|
||||
.readObject(IBlockProcessor.BLOCKS_KEY, null);
|
||||
if (blocks == null)
|
||||
blocks = new HashMap<String, List<IDIYComponent<?>>>();
|
||||
List<IDIYComponent<?>> blockComponents = new ArrayList<IDIYComponent<?>>(selectedComponents);
|
||||
Collections.sort(blockComponents, new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@Override
|
||||
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||
return new Integer(allComponents.indexOf(o1)).compareTo(allComponents.indexOf(o2));
|
||||
}
|
||||
});
|
||||
blocks.put(blockName, blockComponents);
|
||||
|
||||
if (System.getProperty("org.diylc.WriteStaticBlocks", "false").equalsIgnoreCase("true")) {
|
||||
Map<String, List<IDIYComponent<?>>> defaultBlockMap =
|
||||
new HashMap<String, List<IDIYComponent<?>>>();
|
||||
// unify default and user-variants
|
||||
for (Map.Entry<String, List<IDIYComponent<?>>> entry : blocks.entrySet()) {
|
||||
if (defaultBlockMap.containsKey(entry.getKey())) {
|
||||
defaultBlockMap.get(entry.getKey()).addAll(entry.getValue());
|
||||
} else {
|
||||
defaultBlockMap.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
try {
|
||||
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(BLOCKS_FILE_NAME));
|
||||
XStream xStream = new XStream(new DomDriver());
|
||||
xStream.addPermission(AnyTypePermission.ANY);
|
||||
xStream.toXML(defaultBlockMap, out);
|
||||
out.close();
|
||||
// no more user variants
|
||||
configManager.writeValue(IBlockProcessor.BLOCKS_KEY, null);
|
||||
LOG.info("Saved default blocks");
|
||||
} catch (IOException e) {
|
||||
LOG.error("Could not save default blocks", e);
|
||||
}
|
||||
} else {
|
||||
configManager.writeValue(IBlockProcessor.BLOCKS_KEY, blocks);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void deleteBlock(String blockName) {
|
||||
LOG.debug(String.format("deleteBlock(%s)", blockName));
|
||||
Map<String, List<IDIYComponent<?>>> blocks =
|
||||
(Map<String, List<IDIYComponent<?>>>) configManager.readObject(IBlockProcessor.BLOCKS_KEY, null);
|
||||
if (blocks != null) {
|
||||
blocks.remove(blockName);
|
||||
configManager.writeValue(IBlockProcessor.BLOCKS_KEY, blocks);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,6 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -45,8 +44,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.function.Supplier;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.apache.log4j.Logger;
|
||||
@@ -57,7 +54,6 @@ import org.diylc.appframework.simplemq.MessageDispatcher;
|
||||
import org.diylc.appframework.update.Version;
|
||||
import org.diylc.appframework.update.VersionNumber;
|
||||
import org.diylc.clipboard.ComponentTransferable;
|
||||
import org.diylc.common.BuildingBlockPackage;
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.DrawOption;
|
||||
import org.diylc.common.EventType;
|
||||
@@ -69,11 +65,8 @@ import org.diylc.common.IPlugIn;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.IProjectEditor;
|
||||
import org.diylc.common.PropertyWrapper;
|
||||
import org.diylc.common.VariantPackage;
|
||||
import org.diylc.core.ExpansionMode;
|
||||
import org.diylc.core.IContinuity;
|
||||
import org.diylc.core.IDIYComponent;
|
||||
import org.diylc.core.ISwitch;
|
||||
import org.diylc.core.IView;
|
||||
import org.diylc.core.Project;
|
||||
import org.diylc.core.Template;
|
||||
@@ -88,13 +81,11 @@ import org.diylc.netlist.Netlist;
|
||||
import org.diylc.netlist.NetlistAnalyzer;
|
||||
import org.diylc.netlist.NetlistBuilder;
|
||||
import org.diylc.netlist.NetlistException;
|
||||
import org.diylc.netlist.Node;
|
||||
import org.diylc.netlist.Position;
|
||||
import org.diylc.netlist.SwitchSetup;
|
||||
import org.diylc.serialization.ProjectFileManager;
|
||||
import org.diylc.test.DIYTest;
|
||||
import org.diylc.test.Snapshot;
|
||||
import org.diylc.utils.Constants;
|
||||
import org.diylc.utils.ReflectionUtils;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
import com.thoughtworks.xstream.io.xml.DomDriver;
|
||||
import com.thoughtworks.xstream.security.AnyTypePermission;
|
||||
@@ -131,7 +122,6 @@ public class Presenter implements IPlugInPort {
|
||||
private static final String ERROR_NEW = LangUtil.translate("Could not create a new file. Check the log for details.");
|
||||
private static final String ERROR = LangUtil.translate("Error");
|
||||
private static final String APPLY_ERROR = LangUtil.translate("Could not apply changes. Check the log for details.");
|
||||
private static final String MAX_SWITCH_COMBINATIONS_ERROR = LangUtil.translate("Maximum number of switching combinations exceeded. Allowed: %s, actual: %s");
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(Presenter.class);
|
||||
|
||||
@@ -169,16 +159,11 @@ public class Presenter implements IPlugInPort {
|
||||
|
||||
public static final int ICON_SIZE = 32;
|
||||
|
||||
private static final int MAX_RECENT_FILES = 20;
|
||||
private static final int MAX_SWITCH_COMBINATIONS = 64;
|
||||
private static final int MAX_RECENT_FILES = 20;
|
||||
|
||||
private Project currentProject;
|
||||
private Map<String, List<ComponentType>> componentTypes;
|
||||
/**
|
||||
* {@link List} of {@link IAutoCreator} objects that are capable of creating more components
|
||||
* automatically when a component is created, e.g. Solder Pads.
|
||||
*/
|
||||
private List<IAutoCreator> autoCreators;
|
||||
|
||||
// Maps component class names to ComponentType objects.
|
||||
private List<IPlugIn> plugIns;
|
||||
|
||||
@@ -193,6 +178,8 @@ public class Presenter implements IPlugInPort {
|
||||
private DrawingManager drawingManager;
|
||||
private ProjectFileManager projectFileManager;
|
||||
private InstantiationManager instantiationManager;
|
||||
private VariantManager variantManager;
|
||||
private BuildingBlockManager buildingBlockManager;
|
||||
|
||||
private Rectangle selectionRect;
|
||||
|
||||
@@ -232,13 +219,15 @@ public class Presenter implements IPlugInPort {
|
||||
drawingManager = new DrawingManager(messageDispatcher, configManager);
|
||||
projectFileManager = new ProjectFileManager(messageDispatcher);
|
||||
instantiationManager = new InstantiationManager();
|
||||
variantManager = new VariantManager(configManager, projectFileManager.getXStream());
|
||||
buildingBlockManager = new BuildingBlockManager(configManager, projectFileManager.getXStream(), instantiationManager);
|
||||
|
||||
// lockedLayers = EnumSet.noneOf(ComponentLayer.class);
|
||||
// visibleLayers = EnumSet.allOf(ComponentLayer.class);
|
||||
if (importVariantsAndBlocks) {
|
||||
upgradeVariants();
|
||||
importDefaultVariants();
|
||||
importDefaultBlocks();
|
||||
variantManager.upgradeVariants(getComponentTypes());
|
||||
variantManager.importDefaultVariants();
|
||||
buildingBlockManager.importDefaultBlocks();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,25 +480,6 @@ public class Presenter implements IPlugInPort {
|
||||
return componentTypes;
|
||||
}
|
||||
|
||||
public 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.newInstance());
|
||||
LOG.debug("Loaded auto-creator: " + clazz.getName());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error loading auto-creator types", e);
|
||||
}
|
||||
}
|
||||
return autoCreators;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
private boolean isComponentVisible(IDIYComponent<?> component) {
|
||||
ComponentType componentType =
|
||||
@@ -1798,11 +1768,6 @@ public class Presenter implements IPlugInPort {
|
||||
configManager.writeValue(DEFAULTS_KEY_PREFIX + clazz.getName() + ":" + propertyName, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetric(boolean isMetric) {
|
||||
configManager.writeValue(Presenter.METRIC_KEY, isMetric);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void groupSelectedComponents() {
|
||||
LOG.info("groupSelectedComponents()");
|
||||
@@ -2310,23 +2275,6 @@ public class Presenter implements IPlugInPort {
|
||||
return new Point2D[] {inSize, cmSize};
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Rectangle2D getSelectedAreaRect() {
|
||||
// if (selectedComponents.isEmpty()) {
|
||||
// return null;
|
||||
// }
|
||||
// Area area = new Area();
|
||||
// for (IDIYComponent<?> component : selectedComponents) {
|
||||
// Area componentArea = drawingManager.getComponentArea(component);
|
||||
// if (componentArea != null) {
|
||||
// area.add(componentArea);
|
||||
// } else {
|
||||
// LOG.warn("No area found for: " + component.getName());
|
||||
// }
|
||||
// }
|
||||
// return area.getBounds2D();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Adds a component to the project taking z-order into account.
|
||||
*
|
||||
@@ -2351,7 +2299,7 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
|
||||
// Check if we should auto-create something.
|
||||
for (IAutoCreator creator : this.getAutoCreators()) {
|
||||
for (IAutoCreator creator : ReflectionUtils.getAutoCreators()) {
|
||||
List<IDIYComponent<?>> newComponents = creator.createIfNeeded(component);
|
||||
if (newComponents != null) {
|
||||
for (IDIYComponent<?> c : newComponents)
|
||||
@@ -2624,108 +2572,9 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void importDefaultVariants() {
|
||||
// import default templates from variants.xml file only if we didn't do it already
|
||||
if (!configManager.readBoolean(DEFAULT_TEMPLATES_IMPORTED_KEY, false)) {
|
||||
try {
|
||||
URL resource = Presenter.class.getResource("variants.xml");
|
||||
if (resource != null) {
|
||||
BufferedInputStream in = new BufferedInputStream(resource.openStream());
|
||||
Map<String, List<Template>> defaults = (Map<String, List<Template>>) ProjectFileManager.xStreamSerializer.fromXML(in);
|
||||
in.close();
|
||||
|
||||
Map<String, List<Template>> variantMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(TEMPLATES_KEY, null);
|
||||
if (variantMap == null)
|
||||
variantMap = new HashMap<String, List<Template>>();
|
||||
|
||||
// merge default variants with user's
|
||||
for (Map.Entry<String, List<Template>> entry : defaults.entrySet()) {
|
||||
List<Template> templates = variantMap.getOrDefault(entry.getKey(), null);
|
||||
if (templates == null) {
|
||||
templates = new ArrayList<Template>();
|
||||
variantMap.put(entry.getKey(), templates);
|
||||
}
|
||||
templates.addAll(entry.getValue());
|
||||
}
|
||||
|
||||
// update templates and a flag marking that we imported them
|
||||
configManager.writeValue(DEFAULT_TEMPLATES_IMPORTED_KEY, true);
|
||||
configManager.writeValue(TEMPLATES_KEY, variantMap);
|
||||
LOG.info(String.format("Imported default variants for %d components",
|
||||
defaults == null ? 0 : defaults.size()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not load default variants", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void importDefaultBlocks() {
|
||||
// import default templates from variants.xml file only if we didn't do it already
|
||||
if (!configManager.readBoolean(DEFAULT_BLOCKS_IMPORTED_KEY, false)) {
|
||||
try {
|
||||
URL resource = Presenter.class.getResource("blocks.xml");
|
||||
if (resource != null) {
|
||||
BufferedInputStream in = new BufferedInputStream(resource.openStream());
|
||||
Map<String, List<IDIYComponent<?>>> defaults = (Map<String, List<IDIYComponent<?>>>) ProjectFileManager.xStreamSerializer.fromXML(in);
|
||||
in.close();
|
||||
|
||||
Map<String, List<IDIYComponent<?>>> blocksMap =
|
||||
(Map<String, List<IDIYComponent<?>>>) configManager.readObject(BLOCKS_KEY, null);
|
||||
if (blocksMap == null)
|
||||
blocksMap = new HashMap<String, List<IDIYComponent<?>>>();
|
||||
|
||||
// merge default blocks with user's
|
||||
for (Map.Entry<String, List<IDIYComponent<?>>> entry : defaults.entrySet()) {
|
||||
if (!blocksMap.containsKey(entry.getKey()))
|
||||
blocksMap.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
// update templates and a flag marking that we imported them
|
||||
configManager.writeValue(DEFAULT_BLOCKS_IMPORTED_KEY, true);
|
||||
configManager.writeValue(BLOCKS_KEY, blocksMap);
|
||||
LOG.info(String.format("Imported %d default building blocks", defaults == null ? 0 : defaults.size()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not load default blocks", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<Template> getVariantsFor(ComponentType type) {
|
||||
Map<String, List<Template>> lookupMap = new TreeMap<String, List<Template>>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
Map<String, List<Template>> variantMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(TEMPLATES_KEY, null);
|
||||
if (variantMap != null)
|
||||
lookupMap.putAll(variantMap);
|
||||
|
||||
// try by class name and then by old category.type format
|
||||
String key1 = type.getInstanceClass().getCanonicalName();
|
||||
String key2 = type.getCategory() + "." + type.getName();
|
||||
|
||||
List<Template> variants = new ArrayList<Template>();
|
||||
if (variantMap != null) {
|
||||
List<Template> userVariants = variantMap.get(key1);
|
||||
if (userVariants != null && !userVariants.isEmpty())
|
||||
variants.addAll(userVariants);
|
||||
userVariants = variantMap.get(key2);
|
||||
if (userVariants != null && !userVariants.isEmpty())
|
||||
variants.addAll(userVariants);
|
||||
}
|
||||
Collections.sort(variants, new Comparator<Template>() {
|
||||
|
||||
@Override
|
||||
public int compare(Template o1, Template o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
});
|
||||
return variants;
|
||||
return variantManager.getVariantsFor(type);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -2773,40 +2622,10 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
messageDispatcher.dispatchMessage(EventType.REPAINT);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@Override
|
||||
public void deleteVariant(ComponentType type, String templateName) {
|
||||
LOG.debug(String.format("deleteTemplate(%s, %s)", type, templateName));
|
||||
Map<String, List<Template>> templateMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(TEMPLATES_KEY, null);
|
||||
if (templateMap != null) {
|
||||
// try by class name and then by old category.type format
|
||||
String key1 = type.getInstanceClass().getCanonicalName();
|
||||
String key2 = type.getCategory() + "." + type.getName();
|
||||
|
||||
List<Template> templates = templateMap.get(key1);
|
||||
if (templates != null) {
|
||||
Iterator<Template> i = templates.iterator();
|
||||
while (i.hasNext()) {
|
||||
Template t = i.next();
|
||||
if (t.getName().equalsIgnoreCase(templateName)) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
templates = templateMap.get(key2);
|
||||
if (templates != null) {
|
||||
Iterator<Template> i = templates.iterator();
|
||||
while (i.hasNext()) {
|
||||
Template t = i.next();
|
||||
if (t.getName().equalsIgnoreCase(templateName)) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
configManager.writeValue(TEMPLATES_KEY, templateMap);
|
||||
variantManager.deleteVariant(type, templateName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -2833,21 +2652,9 @@ public class Presenter implements IPlugInPort {
|
||||
configManager.writeValue(DEFAULT_TEMPLATES_KEY, defaultTemplateMap);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public String getDefaultVariant(ComponentType type) {
|
||||
Map<String, String> defaultTemplateMap =
|
||||
(Map<String, String>) configManager.readObject(DEFAULT_TEMPLATES_KEY, null);
|
||||
if (defaultTemplateMap == null)
|
||||
return null;
|
||||
|
||||
String key1 = type.getInstanceClass().getCanonicalName();
|
||||
String key2 = type.getCategory() + "." + type.getName();
|
||||
|
||||
if (defaultTemplateMap.containsKey(key1))
|
||||
return defaultTemplateMap.get(key1);
|
||||
|
||||
return defaultTemplateMap.get(key2);
|
||||
return variantManager.getDefaultVariant(type);
|
||||
}
|
||||
|
||||
private Set<IDIYComponent<?>> getLockedComponents() {
|
||||
@@ -2920,94 +2727,21 @@ public class Presenter implements IPlugInPort {
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@Override
|
||||
public void saveSelectionAsBlock(String blockName) {
|
||||
LOG.debug(String.format("saveSelectionAsBlock(%s)", blockName));
|
||||
Map<String, List<IDIYComponent<?>>> blocks =
|
||||
(Map<String, List<IDIYComponent<?>>>) configManager.readObject(BLOCKS_KEY, null);
|
||||
if (blocks == null)
|
||||
blocks = new HashMap<String, List<IDIYComponent<?>>>();
|
||||
List<IDIYComponent<?>> blockComponents = new ArrayList<IDIYComponent<?>>(this.selectedComponents);
|
||||
Collections.sort(blockComponents, new Comparator<IDIYComponent<?>>() {
|
||||
|
||||
@Override
|
||||
public int compare(IDIYComponent<?> o1, IDIYComponent<?> o2) {
|
||||
return new Integer(currentProject.getComponents().indexOf(o1)).compareTo(currentProject.getComponents()
|
||||
.indexOf(o2));
|
||||
}
|
||||
});
|
||||
blocks.put(blockName, blockComponents);
|
||||
|
||||
if (System.getProperty("org.diylc.WriteStaticBlocks", "false").equalsIgnoreCase("true")) {
|
||||
Map<String, List<IDIYComponent<?>>> defaultBlockMap = new HashMap<String, List<IDIYComponent<?>>>();
|
||||
// unify default and user-variants
|
||||
for (Map.Entry<String, List<IDIYComponent<?>>> entry : blocks.entrySet()) {
|
||||
if (defaultBlockMap.containsKey(entry.getKey())) {
|
||||
defaultBlockMap.get(entry.getKey()).addAll(entry.getValue());
|
||||
} else {
|
||||
defaultBlockMap.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
try {
|
||||
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("blocks.xml"));
|
||||
XStream xStream = new XStream(new DomDriver());
|
||||
xStream.addPermission(AnyTypePermission.ANY);
|
||||
xStream.toXML(defaultBlockMap, out);
|
||||
out.close();
|
||||
// no more user variants
|
||||
configManager.writeValue(BLOCKS_KEY, null);
|
||||
LOG.info("Saved default blocks");
|
||||
} catch (IOException e) {
|
||||
LOG.error("Could not save default blocks", e);
|
||||
}
|
||||
} else {
|
||||
configManager.writeValue(BLOCKS_KEY, blocks);
|
||||
}
|
||||
buildingBlockManager.saveSelectionAsBlock(blockName, this.getSelectedComponents(), this.currentProject.getComponents());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void loadBlock(String blockName) throws InvalidBlockException {
|
||||
LOG.debug(String.format("loadBlock(%s)", blockName));
|
||||
Map<String, List<IDIYComponent<?>>> blocks =
|
||||
(Map<String, List<IDIYComponent<?>>>) configManager.readObject(BLOCKS_KEY, null);
|
||||
if (blocks != null) {
|
||||
Collection<IDIYComponent<?>> components = blocks.get(blockName);
|
||||
if (components == null)
|
||||
throw new InvalidBlockException();
|
||||
// clear potential control point every time!
|
||||
instantiationManager.setPotentialControlPoint(null);
|
||||
// clone components
|
||||
List<IDIYComponent<?>> clones = new ArrayList<IDIYComponent<?>>();
|
||||
List<IDIYComponent<?>> testComponents = new ArrayList<IDIYComponent<?>>(currentProject.getComponents());
|
||||
for (IDIYComponent<?> c : components)
|
||||
try {
|
||||
IDIYComponent<?> clone = c.clone();
|
||||
clone.setName(instantiationManager.createUniqueName(ComponentProcessor.getInstance()
|
||||
.extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) clone.getClass()), testComponents));
|
||||
testComponents.add(clone);
|
||||
clones.add(clone);
|
||||
} catch (CloneNotSupportedException e) {
|
||||
LOG.error("Could not clone component: " + c);
|
||||
}
|
||||
// paste them to the project
|
||||
pasteComponents(new ComponentTransferable(clones), true, true);
|
||||
} else
|
||||
throw new InvalidBlockException();
|
||||
public void loadBlock(String blockName) throws InvalidBlockException {
|
||||
List<IDIYComponent<?>> components = buildingBlockManager.loadBlock(blockName, currentProject.getComponents());
|
||||
pasteComponents(new ComponentTransferable(components), true, true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void deleteBlock(String blockName) {
|
||||
LOG.debug(String.format("deleteBlock(%s)", blockName));
|
||||
Map<String, List<IDIYComponent<?>>> blocks =
|
||||
(Map<String, List<IDIYComponent<?>>>) configManager.readObject(BLOCKS_KEY, null);
|
||||
if (blocks != null) {
|
||||
blocks.remove(blockName);
|
||||
configManager.writeValue(BLOCKS_KEY, blocks);
|
||||
}
|
||||
buildingBlockManager.deleteBlock(blockName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3026,260 +2760,21 @@ public class Presenter implements IPlugInPort {
|
||||
return extraSpace;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public int importVariants(String fileName) throws IOException {
|
||||
LOG.debug(String.format("importVariants(%s)", fileName));
|
||||
BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileName));
|
||||
XStream xStream = projectFileManager.getXStream();
|
||||
|
||||
VariantPackage pkg = (VariantPackage) xStream.fromXML(in);
|
||||
|
||||
in.close();
|
||||
|
||||
if (pkg == null || pkg.getVariants().isEmpty())
|
||||
return 0;
|
||||
|
||||
Map<String, List<Template>> variantMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(TEMPLATES_KEY, null);
|
||||
if (variantMap == null) {
|
||||
variantMap = new HashMap<String, List<Template>>();
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<Template>> entry : pkg.getVariants().entrySet()) {
|
||||
List<Template> templates;
|
||||
templates = variantMap.get(entry.getKey());
|
||||
if (templates == null) {
|
||||
templates = new ArrayList<Template>();
|
||||
variantMap.put(entry.getKey(), templates);
|
||||
}
|
||||
for (Template t : entry.getValue()) {
|
||||
templates.add(new Template(t.getName() + " [" + pkg.getOwner() + "]", t.getValues(), t.getPoints()));
|
||||
}
|
||||
}
|
||||
|
||||
configManager.writeValue(TEMPLATES_KEY, variantMap);
|
||||
|
||||
LOG.info(String.format("Loaded variants for %d components", pkg.getVariants().size()));
|
||||
|
||||
return pkg.getVariants().size();
|
||||
return variantManager.importVariants(fileName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@Override
|
||||
public int importBlocks(String fileName) throws IOException {
|
||||
LOG.debug(String.format("importBlocks(%s)", fileName));
|
||||
BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileName));
|
||||
XStream xStream = projectFileManager.getXStream();
|
||||
|
||||
BuildingBlockPackage pkg = (BuildingBlockPackage) xStream.fromXML(in);
|
||||
|
||||
in.close();
|
||||
|
||||
if (pkg == null || pkg.getBlocks().isEmpty())
|
||||
return 0;
|
||||
|
||||
Map<String, List<IDIYComponent<?>>> blocks =
|
||||
(Map<String, List<IDIYComponent<?>>>) configManager.readObject(BLOCKS_KEY, null);
|
||||
if (blocks == null) {
|
||||
blocks = new HashMap<String, List<IDIYComponent<?>>>();
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<IDIYComponent<?>>> entry : pkg.getBlocks().entrySet()) {
|
||||
blocks.put(entry.getKey() + " [" + pkg.getOwner() + "]", entry.getValue());
|
||||
}
|
||||
|
||||
configManager.writeValue(BLOCKS_KEY, blocks);
|
||||
|
||||
LOG.info(String.format("Loaded building blocks for %d components", pkg.getBlocks().size()));
|
||||
|
||||
return pkg.getBlocks().size();
|
||||
return buildingBlockManager.importBlocks(fileName);
|
||||
}
|
||||
|
||||
private static boolean upgradedVariants = false;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private synchronized void upgradeVariants() {
|
||||
if (upgradedVariants)
|
||||
return;
|
||||
|
||||
upgradedVariants = true;
|
||||
|
||||
LOG.info("Checking if variants need to be updated");
|
||||
Map<String, List<Template>> lookupMap = new TreeMap<String, List<Template>>(String.CASE_INSENSITIVE_ORDER);
|
||||
Map<String, List<Template>> variantMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(TEMPLATES_KEY, null);
|
||||
|
||||
if (variantMap == null)
|
||||
return;
|
||||
|
||||
Map<String, ComponentType> typeMap = new TreeMap<String, ComponentType>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
Map<String, List<ComponentType>> componentTypes = getComponentTypes();
|
||||
for (Map.Entry<String, List<ComponentType>> entry : componentTypes.entrySet())
|
||||
for (ComponentType type : entry.getValue()) {
|
||||
typeMap.put(type.getInstanceClass().getCanonicalName(), type);
|
||||
typeMap.put(type.getCategory() + "." + type.getName(), type);
|
||||
if (type.getCategory().contains("Electro-Mechanical"))
|
||||
typeMap.put(type.getCategory().replace("Electro-Mechanical", "Electromechanical") + "." + type.getName(),
|
||||
type);
|
||||
}
|
||||
|
||||
Map<String, List<Template>> newVariantMap = new HashMap<String, List<Template>>();
|
||||
|
||||
lookupMap.putAll(variantMap);
|
||||
|
||||
for (Map.Entry<String, List<Template>> entry : variantMap.entrySet()) {
|
||||
if (typeMap.containsKey(entry.getKey())) {
|
||||
newVariantMap.put(typeMap.get(entry.getKey()).getInstanceClass().getCanonicalName(), entry.getValue()); // great,
|
||||
// nothing
|
||||
// to
|
||||
// upgrade
|
||||
} else {
|
||||
LOG.warn("Could not upgrade variants for: " + entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
configManager.writeValue(TEMPLATES_KEY, newVariantMap);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<Netlist> extractNetlists(boolean includeSwitches) throws NetlistException {
|
||||
Map<Netlist, Netlist> result = new HashMap<Netlist, Netlist>();
|
||||
List<Node> nodes = new ArrayList<Node>();
|
||||
|
||||
List<ISwitch> switches = new ArrayList<ISwitch>();
|
||||
|
||||
for (IDIYComponent<?> c : currentProject.getComponents()) {
|
||||
ComponentType type =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) c.getClass());
|
||||
|
||||
// extract nodes
|
||||
if (!(c instanceof IContinuity)) {
|
||||
for (int i = 0; i < c.getControlPointCount(); i++) {
|
||||
String nodeName = c.getControlPointNodeName(i);
|
||||
if (nodeName != null && (!includeSwitches || !ISwitch.class.isAssignableFrom(type.getInstanceClass()))) {
|
||||
nodes.add(new Node(c, i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// extract switches
|
||||
if (includeSwitches && ISwitch.class.isAssignableFrom(type.getInstanceClass()))
|
||||
switches.add((ISwitch) c);
|
||||
}
|
||||
|
||||
// save us the trouble
|
||||
if (nodes.isEmpty())
|
||||
return null;
|
||||
|
||||
// if there are no switches, make one with 1 position so we get 1 result back
|
||||
if (switches.isEmpty())
|
||||
switches.add(new ISwitch() {
|
||||
|
||||
@Override
|
||||
public String getPositionName(int position) {
|
||||
return "Default";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPositionCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean arePointsConnected(int index1, int index2, int position) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// construct all possible combinations
|
||||
int[] positions = new int[switches.size()];
|
||||
for (int i = 0; i < switches.size(); i++)
|
||||
positions[i] = 0;
|
||||
|
||||
// grab continuity areas
|
||||
List<Area> continuityAreas = drawingManager.getContinuityAreas(currentProject);
|
||||
|
||||
int i = switches.size() - 1;
|
||||
|
||||
int totalSwitchCombinations = switches.stream()
|
||||
.map(sw -> sw.getPositionCount())
|
||||
.reduce(1, (a, b) -> a * b);
|
||||
|
||||
if (totalSwitchCombinations > MAX_SWITCH_COMBINATIONS) {
|
||||
throw new NetlistException(String.format(MAX_SWITCH_COMBINATIONS_ERROR, MAX_SWITCH_COMBINATIONS, totalSwitchCombinations));
|
||||
}
|
||||
|
||||
while (i >= 0) {
|
||||
// process the current combination
|
||||
Map<ISwitch, Integer> switchPositions = new HashMap<ISwitch, Integer>();
|
||||
List<Position> posList = new ArrayList<Position>();
|
||||
for (int j = 0; j < positions.length; j++) {
|
||||
switchPositions.put(switches.get(j), positions[j]);
|
||||
posList.add(new Position(switches.get(j), positions[j]));
|
||||
}
|
||||
List<Connection> connections = getConnections(switchPositions);
|
||||
|
||||
Netlist netlist = NetlistBuilder.buildNetlist(currentProject.getComponents(), nodes, continuityAreas, connections);
|
||||
|
||||
// merge graphs that are effectively the same
|
||||
if (result.containsKey(netlist)) {
|
||||
result.get(netlist).getSwitchSetup().add(new SwitchSetup(posList));
|
||||
} else {
|
||||
netlist.getSwitchSetup().add(new SwitchSetup(posList));
|
||||
result.put(netlist, netlist);
|
||||
}
|
||||
|
||||
// find the next combination if possible
|
||||
if (positions[i] < switches.get(i).getPositionCount() - 1) {
|
||||
positions[i]++;
|
||||
} else {
|
||||
while (i >= 0 && positions[i] == switches.get(i).getPositionCount() - 1)
|
||||
i--;
|
||||
if (i >= 0) {
|
||||
positions[i]++;
|
||||
for (int j = i + 1; j < positions.length; j++)
|
||||
positions[j] = 0;
|
||||
i = switches.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort everything alphabetically
|
||||
List<Netlist> netlists = new ArrayList<Netlist>(result.keySet());
|
||||
Collections.sort(netlists);
|
||||
|
||||
return netlists;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "unlikely-arg-type"})
|
||||
private List<Connection> getConnections(Map<ISwitch, Integer> switchPositions) {
|
||||
Set<Connection> connections = new TreeSet<Connection>();
|
||||
|
||||
for (IDIYComponent<?> c : currentProject.getComponents()) {
|
||||
ComponentType type =
|
||||
ComponentProcessor.getInstance().extractComponentTypeFrom((Class<? extends IDIYComponent<?>>) c.getClass());
|
||||
// handle direct connections
|
||||
if (c instanceof IContinuity) {
|
||||
for (int i = 0; i < c.getControlPointCount() - 1; i++)
|
||||
for (int j = i + 1; j < c.getControlPointCount(); j++)
|
||||
if (((IContinuity) c).arePointsConnected(i, j))
|
||||
connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j)));
|
||||
}
|
||||
// handle switches
|
||||
if (ISwitch.class.isAssignableFrom(type.getInstanceClass()) && switchPositions.containsKey(c)) {
|
||||
int position = switchPositions.get(c);
|
||||
ISwitch s = (ISwitch) c;
|
||||
for (int i = 0; i < c.getControlPointCount() - 1; i++)
|
||||
for (int j = i + 1; j < c.getControlPointCount(); j++)
|
||||
if (s.arePointsConnected(i, j, position))
|
||||
connections.add(new Connection(c.getControlPoint(i), c.getControlPoint(j)));
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<Connection>(connections);
|
||||
return NetlistBuilder.extractNetlists(includeSwitches, currentProject, continuityAreas);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -3312,30 +2807,7 @@ public class Presenter implements IPlugInPort {
|
||||
|
||||
@Override
|
||||
public 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.newInstance());
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(result, new Comparator<INetlistParser>() {
|
||||
|
||||
@Override
|
||||
public int compare(INetlistParser o1, INetlistParser o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not load INetlistParserDefinition implementations", e);
|
||||
return null;
|
||||
}
|
||||
return ReflectionUtils.getNetlistParserDefinitions();
|
||||
}
|
||||
|
||||
// Test stuff
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
*
|
||||
l * DIY Layout Creator (DIYLC). Copyright (c) 2009-2018 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.io.BufferedInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.diylc.appframework.miscutils.IConfigurationManager;
|
||||
import org.diylc.common.ComponentType;
|
||||
import org.diylc.common.IPlugInPort;
|
||||
import org.diylc.common.VariantPackage;
|
||||
import org.diylc.core.Template;
|
||||
import org.diylc.serialization.ProjectFileManager;
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
public class VariantManager {
|
||||
|
||||
private static final String VARIANTS_FILE_NAME = "variants.xml";
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(VariantManager.class);
|
||||
|
||||
private IConfigurationManager<?> configManager;
|
||||
private XStream xStream;
|
||||
|
||||
public VariantManager(IConfigurationManager<?> configManager, XStream xStream) {
|
||||
super();
|
||||
this.configManager = configManager;
|
||||
this.xStream = xStream;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void importDefaultVariants() {
|
||||
// import default templates from variants.xml file only if we didn't do it already
|
||||
if (!configManager.readBoolean(IPlugInPort.DEFAULT_TEMPLATES_IMPORTED_KEY, false)) {
|
||||
try {
|
||||
URL resource = Presenter.class.getResource(VARIANTS_FILE_NAME);
|
||||
if (resource != null) {
|
||||
BufferedInputStream in = new BufferedInputStream(resource.openStream());
|
||||
Map<String, List<Template>> defaults = (Map<String, List<Template>>) ProjectFileManager.xStreamSerializer.fromXML(in);
|
||||
in.close();
|
||||
|
||||
Map<String, List<Template>> variantMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(IPlugInPort.TEMPLATES_KEY, null);
|
||||
if (variantMap == null)
|
||||
variantMap = new HashMap<String, List<Template>>();
|
||||
|
||||
// merge default variants with user's
|
||||
for (Map.Entry<String, List<Template>> entry : defaults.entrySet()) {
|
||||
List<Template> templates = variantMap.getOrDefault(entry.getKey(), null);
|
||||
if (templates == null) {
|
||||
templates = new ArrayList<Template>();
|
||||
variantMap.put(entry.getKey(), templates);
|
||||
}
|
||||
templates.addAll(entry.getValue());
|
||||
}
|
||||
|
||||
// update templates and a flag marking that we imported them
|
||||
configManager.writeValue(IPlugInPort.DEFAULT_TEMPLATES_IMPORTED_KEY, true);
|
||||
configManager.writeValue(IPlugInPort.TEMPLATES_KEY, variantMap);
|
||||
LOG.info(String.format("Imported default variants for %d components",
|
||||
defaults == null ? 0 : defaults.size()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not load default variants", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean upgradedVariants = false;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized void upgradeVariants(Map<String, List<ComponentType>> componentTypes) {
|
||||
if (upgradedVariants)
|
||||
return;
|
||||
|
||||
upgradedVariants = true;
|
||||
|
||||
LOG.info("Checking if variants need to be updated");
|
||||
Map<String, List<Template>> lookupMap = new TreeMap<String, List<Template>>(String.CASE_INSENSITIVE_ORDER);
|
||||
Map<String, List<Template>> variantMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(IPlugInPort.TEMPLATES_KEY, null);
|
||||
|
||||
if (variantMap == null)
|
||||
return;
|
||||
|
||||
Map<String, ComponentType> typeMap = new TreeMap<String, ComponentType>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
for (Map.Entry<String, List<ComponentType>> entry : componentTypes.entrySet())
|
||||
for (ComponentType type : entry.getValue()) {
|
||||
typeMap.put(type.getInstanceClass().getCanonicalName(), type);
|
||||
typeMap.put(type.getCategory() + "." + type.getName(), type);
|
||||
if (type.getCategory().contains("Electro-Mechanical"))
|
||||
typeMap.put(type.getCategory().replace("Electro-Mechanical", "Electromechanical") + "." + type.getName(),
|
||||
type);
|
||||
}
|
||||
|
||||
Map<String, List<Template>> newVariantMap = new HashMap<String, List<Template>>();
|
||||
|
||||
lookupMap.putAll(variantMap);
|
||||
|
||||
for (Map.Entry<String, List<Template>> entry : variantMap.entrySet()) {
|
||||
if (typeMap.containsKey(entry.getKey())) {
|
||||
newVariantMap.put(typeMap.get(entry.getKey()).getInstanceClass().getCanonicalName(), entry.getValue()); // great,
|
||||
// nothing
|
||||
// to
|
||||
// upgrade
|
||||
} else {
|
||||
LOG.warn("Could not upgrade variants for: " + entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
configManager.writeValue(IPlugInPort.TEMPLATES_KEY, newVariantMap);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<Template> getVariantsFor(ComponentType type) {
|
||||
Map<String, List<Template>> lookupMap = new TreeMap<String, List<Template>>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
Map<String, List<Template>> variantMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(IPlugInPort.TEMPLATES_KEY, null);
|
||||
if (variantMap != null)
|
||||
lookupMap.putAll(variantMap);
|
||||
|
||||
// try by class name and then by old category.type format
|
||||
String key1 = type.getInstanceClass().getCanonicalName();
|
||||
String key2 = type.getCategory() + "." + type.getName();
|
||||
|
||||
List<Template> variants = new ArrayList<Template>();
|
||||
if (variantMap != null) {
|
||||
List<Template> userVariants = variantMap.get(key1);
|
||||
if (userVariants != null && !userVariants.isEmpty())
|
||||
variants.addAll(userVariants);
|
||||
userVariants = variantMap.get(key2);
|
||||
if (userVariants != null && !userVariants.isEmpty())
|
||||
variants.addAll(userVariants);
|
||||
}
|
||||
Collections.sort(variants, new Comparator<Template>() {
|
||||
|
||||
@Override
|
||||
public int compare(Template o1, Template o2) {
|
||||
return o1.getName().compareTo(o2.getName());
|
||||
}
|
||||
});
|
||||
return variants;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public int importVariants(String fileName) throws IOException {
|
||||
LOG.debug(String.format("importVariants(%s)", fileName));
|
||||
BufferedInputStream in = new BufferedInputStream(new FileInputStream(fileName));
|
||||
|
||||
VariantPackage pkg = (VariantPackage) xStream.fromXML(in);
|
||||
|
||||
in.close();
|
||||
|
||||
if (pkg == null || pkg.getVariants().isEmpty())
|
||||
return 0;
|
||||
|
||||
Map<String, List<Template>> variantMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(IPlugInPort.TEMPLATES_KEY, null);
|
||||
if (variantMap == null) {
|
||||
variantMap = new HashMap<String, List<Template>>();
|
||||
}
|
||||
|
||||
for (Map.Entry<String, List<Template>> entry : pkg.getVariants().entrySet()) {
|
||||
List<Template> templates;
|
||||
templates = variantMap.get(entry.getKey());
|
||||
if (templates == null) {
|
||||
templates = new ArrayList<Template>();
|
||||
variantMap.put(entry.getKey(), templates);
|
||||
}
|
||||
for (Template t : entry.getValue()) {
|
||||
templates.add(new Template(t.getName() + " [" + pkg.getOwner() + "]", t.getValues(), t.getPoints()));
|
||||
}
|
||||
}
|
||||
|
||||
configManager.writeValue(IPlugInPort.TEMPLATES_KEY, variantMap);
|
||||
|
||||
LOG.info(String.format("Loaded variants for %d components", pkg.getVariants().size()));
|
||||
|
||||
return pkg.getVariants().size();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public String getDefaultVariant(ComponentType type) {
|
||||
Map<String, String> defaultTemplateMap =
|
||||
(Map<String, String>) configManager.readObject(IPlugInPort.DEFAULT_TEMPLATES_KEY, null);
|
||||
if (defaultTemplateMap == null)
|
||||
return null;
|
||||
|
||||
String key1 = type.getInstanceClass().getCanonicalName();
|
||||
String key2 = type.getCategory() + "." + type.getName();
|
||||
|
||||
if (defaultTemplateMap.containsKey(key1))
|
||||
return defaultTemplateMap.get(key1);
|
||||
|
||||
return defaultTemplateMap.get(key2);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void deleteVariant(ComponentType type, String templateName) {
|
||||
LOG.debug(String.format("deleteTemplate(%s, %s)", type, templateName));
|
||||
Map<String, List<Template>> templateMap =
|
||||
(Map<String, List<Template>>) configManager.readObject(IPlugInPort.TEMPLATES_KEY, null);
|
||||
if (templateMap != null) {
|
||||
// try by class name and then by old category.type format
|
||||
String key1 = type.getInstanceClass().getCanonicalName();
|
||||
String key2 = type.getCategory() + "." + type.getName();
|
||||
|
||||
List<Template> templates = templateMap.get(key1);
|
||||
if (templates != null) {
|
||||
Iterator<Template> i = templates.iterator();
|
||||
while (i.hasNext()) {
|
||||
Template t = i.next();
|
||||
if (t.getName().equalsIgnoreCase(templateName)) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
templates = templateMap.get(key2);
|
||||
if (templates != null) {
|
||||
Iterator<Template> i = templates.iterator();
|
||||
while (i.hasNext()) {
|
||||
Template t = i.next();
|
||||
if (t.getName().equalsIgnoreCase(templateName)) {
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
configManager.writeValue(IPlugInPort.TEMPLATES_KEY, templateMap);
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@ public class Pair<A, B> {
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
@SuppressWarnings("rawtypes")
|
||||
Pair other = (Pair) obj;
|
||||
if (first == null) {
|
||||
if (other.first != null)
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
|
||||
DIY Layout Creator (DIYLC).
|
||||
Copyright (c) 2009-2018 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.utils;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
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.netlist.INetlistParser;
|
||||
import org.diylc.presenter.Presenter;
|
||||
|
||||
public class ReflectionUtils {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(Presenter.class);
|
||||
|
||||
/**
|
||||
* {@link List} of {@link IAutoCreator} objects that are capable of creating more components
|
||||
* automatically when a component is created, e.g. Solder Pads.
|
||||
*/
|
||||
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.newInstance());
|
||||
LOG.debug("Loaded auto-creator: " + clazz.getName());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOG.error("Error loading auto-creator types", e);
|
||||
}
|
||||
}
|
||||
return autoCreators;
|
||||
}
|
||||
|
||||
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.newInstance());
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(result, new Comparator<INetlistParser>() {
|
||||
|
||||
@Override
|
||||
public int compare(INetlistParser o1, INetlistParser o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
LOG.error("Could not load INetlistParserDefinition implementations", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import org.diylc.components.guitar.JazzBassPickup;
|
||||
import org.diylc.components.guitar.P90Pickup;
|
||||
import org.diylc.components.guitar.PBassPickup;
|
||||
import org.diylc.components.guitar.SingleCoilPickup;
|
||||
import org.diylc.components.guitar.StingrayBassPickup;
|
||||
import org.diylc.components.passive.AxialFilmCapacitor;
|
||||
import org.diylc.components.passive.PotentiometerPanel;
|
||||
import org.diylc.components.passive.RadialCeramicDiskCapacitor;
|
||||
@@ -60,6 +61,7 @@ public class GuitarDiagramAnalyzer extends NetlistAnalyzer implements INetlistAn
|
||||
PICKUP_TYPES.add(P90Pickup.class.getCanonicalName());
|
||||
PICKUP_TYPES.add(JazzBassPickup.class.getCanonicalName());
|
||||
PICKUP_TYPES.add(PBassPickup.class.getCanonicalName());
|
||||
PICKUP_TYPES.add(StingrayBassPickup.class.getCanonicalName());
|
||||
|
||||
CAP_TYPES.add(RadialCeramicDiskCapacitor.class.getCanonicalName());
|
||||
CAP_TYPES.add(RadialFilmCapacitor.class.getCanonicalName());
|
||||
|
||||
Reference in New Issue
Block a user