ArduinoSystem.java
/*******************************************************************************
* jArduino: Arduino C++ Code Generation From Java
* Copyright 2020 Tony Washer
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package net.sourceforge.jarduino.message;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import net.sourceforge.jarduino.ArduinoException;
import net.sourceforge.jarduino.message.ArduinoAttribute.ArduinoAttrObject;
import net.sourceforge.jarduino.message.ArduinoParser.ArduinoParserException;
/**
* The system.
*/
public final class ArduinoSystem
implements ArduinoNamedObject, ArduinoAttrObject {
/**
* The name of the system.
*/
private final String theName;
/**
* The Cname of the system.
*/
private final String theCName;
/**
* The list of nodes.
*/
private final List<ArduinoNode> theNodes;
/**
* The core attributes.
*/
private final ArduinoAttributes theCoreAttributes;
/**
* the Map of explicit attributes.
*/
private final Map<ArduinoAttribute, Object> theAttributes;
/**
* The comments.
*/
private final ArduinoComments theComments;
/**
* Constructor.
* @param pName the name
*/
private ArduinoSystem(final String pName) {
/* Store parameters */
theName = pName;
/* Remove problematical characters for the CName */
theCName = theName.replace(ArduinoChar.BLANK, ArduinoChar.UNDERSCORE)
.replace(ArduinoChar.DEC, ArduinoChar.UNDERSCORE);
/* Create the lists and comments */
theNodes = new ArrayList<>();
theAttributes = new HashMap<>();
theCoreAttributes = new ArduinoAttributes();
theComments = new ArduinoComments();
}
/**
* Parse the nodes.
* @param pNodes the nodes string
*/
private void parseNodes(final String pNodes) {
/* Loop through the tokens */
String myNodes = pNodes;
while (myNodes.length() > 0) {
final String myNode = ArduinoParser.nextToken(myNodes);
myNodes = ArduinoParser.stripToken(myNodes, myNode);
theNodes.add(new ArduinoNode(this, myNode));
}
}
@Override
public String getName() {
return theName;
}
/**
* Obtain the CName.
* @return the CName
*/
public String getCName() {
return theCName;
}
/**
* Obtain the nodes in this system.
* @return the nodes
*/
public List<ArduinoNode> getNodes() {
return theNodes;
}
/**
* Obtain a list of all messages in the system.
* @return the messages
*/
public List<ArduinoMessage> getMessages() {
/* Create an empty list */
final List<ArduinoMessage> myList = new ArrayList<>();
/* Loop through the nodes */
for (ArduinoNode myNode : theNodes) {
/* Add all the messages */
myList.addAll(myNode.getMessages());
}
/* return the list */
return myList;
}
/**
* Obtain a list of all attributes in the system.
* @return the messages
*/
public List<ArduinoAttribute> getAttributes() {
/* return the list */
return theCoreAttributes.getAttributes();
}
/**
* Set value for attribute.
* @param pAttr the attribute
* @param pValue the value
* @throws ArduinoParserException on error
*/
void setAttrValue(final ArduinoAttribute pAttr,
final Object pValue) throws ArduinoParserException {
/* Check that this is not a duplicate */
if (theAttributes.containsKey(pAttr)) {
throw new ArduinoParserException("Duplicate Attribute", pAttr.getName());
}
/* Store the value */
theAttributes.put(pAttr, pValue);
}
@Override
public Object getAttrValue(final ArduinoAttribute pAttr) {
final Object myValue = theAttributes.get(pAttr);
return myValue == null ? pAttr.getDefault() : myValue;
}
/**
* find node by name.
* @param pName the node name.
* @return the node
* @throws ArduinoParserException on error
*/
public ArduinoNode findNodeByName(final String pName) throws ArduinoParserException {
/* Loop through the list */
for (ArduinoNode myNode : theNodes) {
if (pName.equals(myNode.getName())) {
return myNode;
}
}
/* If this is the null Node */
if (ArduinoNode.NULL_NODE.equals(pName)) {
/* Add it to the list of nodes and return it */
final ArduinoNode myNode = new ArduinoNode(this, pName);
theNodes.add(myNode);
return myNode;
}
/* Throw error */
throw new ArduinoParserException("Unknown node", pName);
}
/**
* find message by id.
* @param pId the message Id.
* @return the message
* @throws ArduinoParserException on error
*/
ArduinoMessage findMessageById(final String pId) throws ArduinoParserException {
/* Loop through the list */
for (ArduinoNode myNode : theNodes) {
final ArduinoMessage myMessage = myNode.findMessageById(pId);
if (myMessage != null) {
return myMessage;
}
}
/* Not found */
throw new ArduinoParserException("Unknown id: ", pId);
}
/**
* find signal by Id and name.
* @param pId the message Id.
* @param pName the signal name
* @return the signal
* @throws ArduinoParserException on error
*/
ArduinoSignal findSignalByIdAndName(final String pId,
final String pName) throws ArduinoParserException {
/* Find the message */
final ArduinoMessage myMessage = findMessageById(pId);
/* Find the signal */
return myMessage.findSignalByName(pName);
}
/**
* find attribute by name.
* @param pName the signal name
* @return the attribute
* @throws ArduinoParserException on error
*/
ArduinoAttribute findAttributeByName(final String pName) throws ArduinoParserException {
/* Find the attribute */
final ArduinoAttribute myAttr = theCoreAttributes.getAttributeForName(pName);
if (myAttr == null) {
throw new ArduinoParserException("Unknown attribute: ", pName);
}
return myAttr;
}
/**
* Obtain the comment for an object (if any).
* @param pObject the object
* @return the comment (or null)
*/
public String getCommentForObject(final ArduinoNamedObject pObject) {
return theComments.getCommentForObject(pObject);
}
/**
* Store the comment for an object.
* @param pObject the object
* @param pComment the comment
*/
void storeCommentForObject(final ArduinoNamedObject pObject,
final String pComment) {
theComments.storeCommentForObject(pObject, pComment);
}
/**
* Store the attribute.
* @param pAttr the attribute
* @throws ArduinoException on error
*/
void storeAttribute(final ArduinoAttribute pAttr) throws ArduinoException {
theCoreAttributes.storeAttribute(pAttr);
}
/**
* Parse system.
* @param pName the system name
* @param pSystemDef the system representation
* @return the system
* @throws ArduinoException on error
*/
static ArduinoSystem parseSystem(final String pName,
final String pSystemDef) throws ArduinoException {
/* Marker is first token in header */
final String myMarker = ArduinoParser.nextToken(pSystemDef);
final String myNodes = ArduinoParser.stripToken(pSystemDef, myMarker);
if (!myMarker.equals(ArduinoNode.MARKER + ArduinoChar.COLON)) {
throw new ArduinoException("Invalid marker", pSystemDef);
}
/* Create the system */
final ArduinoSystem mySystem = new ArduinoSystem(pName);
/* Parse the nodes */
mySystem.parseNodes(myNodes);
/* Return the parsed system */
return mySystem;
}
@Override
public boolean equals(final Object pThat) {
/* Handle trivial cases */
if (pThat == this) {
return true;
} else if (!(pThat instanceof ArduinoSystem)) {
return false;
}
/* Access correctly */
final ArduinoSystem myThat = (ArduinoSystem) pThat;
/* Check name */
return theName.equals(myThat.getName());
}
@Override
public int hashCode() {
return Objects.hashCode(theName);
}
@Override
public String toString() {
return theName;
}
}