+/* $Id: RtemsVisitor.java 1 2010-02-24 13:03:05Z haidw $ */
+package dol.visitor.rtems;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Vector;
+
+import dol.datamodel.pn.Port;
+import dol.datamodel.pn.Process;
+import dol.datamodel.pn.ProcessNetwork;
+import dol.util.Copier;
+import dol.visitor.PNVisitor;
+
+/**
+ * This class is a class for a visitor that is used to generate
+ * a RTEMS package.
+ */
+public class RtemsVisitor extends PNVisitor {
+
+ /**
+ * Constructor.
+ *
+ * @param packageName name of the Rtems directory
+ */
+ public RtemsVisitor(String packageName) {
+ _packageName = packageName;
+ }
+
+ /**
+ * Visit process network.
+ *
+ * @param pn process network that needs to be rendered.
+ */
+ public void visitComponent(ProcessNetwork pn) {
+ try {
+ File dir = new File(_packageName);
+ dir.mkdirs();
+
+ //copy library files
+ File source = new File(_ui.getMySystemCLib().
+ replaceAll("systemC", "rtems"));
+ new Copier().copy(source, dir);
+
+ //copy process source code
+ source = new File(_srcDirName);
+ new Copier().copy(source, dir);
+
+ createPortMap(pn);
+ createSinkMap(pn);
+ pn.accept(new RtemsMakefileVisitor(_packageName));
+ pn.accept(new RtemsProcessVisitor(_packageName,_portMap,_sinkMap));
+ pn.accept(new RtemsModuleVisitor(_packageName, _portMap));
+ pn.accept(new RtemsShaperVisitor(_packageName, _sinkMap));
+ pn.accept(new RtemsPropertiesVisitor(_packageName));
+ }
+ catch (Exception e) {
+ System.out.println("RtemsVisitor: exception occured: "
+ + e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Create a hashmap which maps each port of the given process network
+ * to an integer. For each process, ports are numbered with integers
+ * starting from 0.
+ *
+ * @param pn process network for which the map should be generated
+ */
+ protected void createPortMap(ProcessNetwork pn) {
+ _portMap = new HashMap<Port, Integer>();
+
+ for (Process process : pn.getProcessList()) {
+ int portCount = 0;
+ Vector<Port> portList = process.getPortList();
+ Vector<String> portNameList = new Vector<String>();
+ portNameList.clear();
+ HashMap<String, Integer> portMap =
+ new HashMap<String, Integer>();
+ portMap.clear();
+
+ for (int i = 0; i < portList.size(); i++) {
+ //treat single ports differently than iterated ports
+ String portName = portList.elementAt(i).getName();
+ String baseName = portList.elementAt(i).getBasename();
+
+ if (portName.equals(baseName)) {
+ portNameList.add(portName);
+ portMap.put(portName, portCount++);
+ } else {
+ String range_indices = portList.elementAt(i).getRange();
+ Vector<Integer> range_indices_values = getIndex(range_indices, ";");
+
+ String port_indices = portName;
+ port_indices.replaceAll(baseName, "");
+ Vector<Integer> port_indices_values = getIndex(port_indices, "_");
+
+ if (!portNameList.contains(baseName)) {
+ portNameList.add(baseName);
+ portMap.put(baseName, portCount);
+
+ int size = 1;
+ for (int j = 0; j < range_indices_values.size(); j++) {
+ size *= range_indices_values.elementAt(j);
+ }
+ portCount += size;
+ }
+
+ int portId = portMap.get(baseName);
+ for (int j = 0; j < port_indices_values.size(); j++) {
+ int weight = 1;
+ for (int k = j + 1; k < range_indices_values.size(); k++) {
+ weight *= range_indices_values.elementAt(k);
+ }
+ portId += port_indices_values.elementAt(j) * weight;
+ }
+ portMap.put(portName, portId);
+ }
+ }
+
+ for (int i = 0; i < portList.size(); i++) {
+ _portMap.put(portList.elementAt(i),
+ portMap.get(portList.elementAt(i).getName()));
+ }
+ }
+ }
+
+
+ /**
+ * Create a hashmap which maps each sink of the given process network
+ * to an integer. For each process, sinks are numbered with integers
+ * starting from 1.
+ *
+ * @param pn process network for which the map should be generated
+ */
+ protected void createSinkMap(ProcessNetwork pn) {
+ _sinkMap = new HashMap<Process, Integer>();
+ int i = 1;
+
+ for (Process process : pn.getProcessList()) {
+ if (!process.hasOutPorts()) {
+ _sinkMap.put(process, i);
+ i++;
+ }
+ }
+ }
+
+ /**
+ * Gets vector of indices of a string, where the index must be
+ * separated by the specified separator.
+ * examples:
+ * getIndex("name_1_2", "_", 0) will return 1.
+ * getIndex("name_1_2", "_", 1) will return 2.
+ *
+ * @param range string to parse
+ * @param separator delimiter of indices
+ * @return vector of indices
+ */
+ protected Vector<Integer> getIndex(String range, String separator) {
+ Vector<Integer> indices = new Vector<Integer>();
+ String[] subranges = range.split(separator);
+ for (int i = 0; i < subranges.length; i++) {
+ try {
+ int value = Integer.valueOf(subranges[i]);
+ indices.add(value);
+ } catch (Exception e) {
+ continue;
+ }
+ }
+ return indices;
+ }
+
+ protected HashMap<Port, Integer> _portMap;
+ protected HashMap<Process, Integer> _sinkMap;
+ protected String _packageName = null;
+
+ protected String _srcDir = "";
+ protected static String _srcDirName = "src";
+}