View Javadoc
1   /*******************************************************************************
2    * jArduino: Arduino C++ Code Generation From Java
3    * Copyright 2020 Tony Washer
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   ******************************************************************************/
17  package net.sourceforge.jarduino.message;
18  
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.Objects;
24  
25  import net.sourceforge.jarduino.ArduinoException;
26  import net.sourceforge.jarduino.message.ArduinoAttribute.ArduinoAttrObject;
27  import net.sourceforge.jarduino.message.ArduinoParser.ArduinoParserException;
28  
29  /**
30   * The system.
31   */
32  public final class ArduinoSystem
33          implements ArduinoNamedObject, ArduinoAttrObject {
34      /**
35       * The name of the system.
36       */
37      private final String theName;
38  
39      /**
40       * The Cname of the system.
41       */
42      private final String theCName;
43  
44      /**
45       * The list of nodes.
46       */
47      private final List<ArduinoNode> theNodes;
48  
49      /**
50       * The core attributes.
51       */
52      private final ArduinoAttributes theCoreAttributes;
53  
54      /**
55       * the Map of explicit attributes.
56       */
57      private final Map<ArduinoAttribute, Object> theAttributes;
58  
59      /**
60       * The comments.
61       */
62      private final ArduinoComments theComments;
63  
64      /**
65       * Constructor.
66       * @param pName the name
67       */
68      private ArduinoSystem(final String pName) {
69          /* Store parameters */
70          theName = pName;
71  
72          /* Remove problematical characters for the CName */
73          theCName = theName.replace(ArduinoChar.BLANK, ArduinoChar.UNDERSCORE)
74                  .replace(ArduinoChar.DEC, ArduinoChar.UNDERSCORE);
75  
76          /* Create the lists and comments */
77          theNodes = new ArrayList<>();
78          theAttributes = new HashMap<>();
79          theCoreAttributes = new ArduinoAttributes();
80          theComments = new ArduinoComments();
81      }
82  
83      /**
84       * Parse the nodes.
85       * @param pNodes the nodes string
86       */
87      private void parseNodes(final String pNodes) {
88          /* Loop through the tokens */
89          String myNodes = pNodes;
90          while (myNodes.length() > 0) {
91              final String myNode = ArduinoParser.nextToken(myNodes);
92              myNodes = ArduinoParser.stripToken(myNodes, myNode);
93              theNodes.add(new ArduinoNode(this, myNode));
94          }
95      }
96  
97      @Override
98      public String getName() {
99          return theName;
100     }
101 
102     /**
103      * Obtain the CName.
104      * @return the CName
105      */
106     public String getCName() {
107         return theCName;
108     }
109 
110     /**
111      * Obtain the nodes in this system.
112      * @return the nodes
113      */
114     public List<ArduinoNode> getNodes() {
115         return theNodes;
116     }
117 
118     /**
119      * Obtain a list of all messages in the system.
120      * @return the messages
121      */
122     public List<ArduinoMessage> getMessages() {
123         /* Create an empty list */
124         final List<ArduinoMessage> myList = new ArrayList<>();
125 
126         /* Loop through the nodes */
127         for (ArduinoNode myNode : theNodes) {
128             /* Add all the messages */
129             myList.addAll(myNode.getMessages());
130         }
131 
132         /* return the list */
133          return myList;
134     }
135 
136     /**
137      * Obtain a list of all attributes in the system.
138      * @return the messages
139      */
140     public List<ArduinoAttribute> getAttributes() {
141         /* return the list */
142         return theCoreAttributes.getAttributes();
143     }
144 
145     /**
146      * Set value for attribute.
147      * @param pAttr the attribute
148      * @param pValue the value
149      * @throws ArduinoParserException on error
150      */
151     void setAttrValue(final ArduinoAttribute pAttr,
152                       final Object pValue) throws ArduinoParserException {
153         /* Check that this is not a duplicate */
154         if (theAttributes.containsKey(pAttr)) {
155             throw new ArduinoParserException("Duplicate Attribute",  pAttr.getName());
156         }
157 
158         /* Store the value */
159         theAttributes.put(pAttr, pValue);
160     }
161 
162     @Override
163     public Object getAttrValue(final ArduinoAttribute pAttr) {
164         final Object myValue = theAttributes.get(pAttr);
165         return myValue == null ? pAttr.getDefault() : myValue;
166     }
167 
168     /**
169      * find node by name.
170      * @param pName the node name.
171      * @return the node
172      * @throws ArduinoParserException on error
173      */
174     public ArduinoNode findNodeByName(final String pName) throws ArduinoParserException {
175         /* Loop through the list */
176         for (ArduinoNode myNode : theNodes) {
177             if (pName.equals(myNode.getName())) {
178                 return myNode;
179             }
180         }
181 
182         /* If this is the null Node */
183         if (ArduinoNode.NULL_NODE.equals(pName)) {
184             /* Add it to the list of nodes and return it */
185             final ArduinoNodeArduinoNode.html#ArduinoNode">ArduinoNode myNode = new ArduinoNode(this, pName);
186             theNodes.add(myNode);
187             return myNode;
188         }
189 
190         /* Throw error */
191         throw new ArduinoParserException("Unknown node", pName);
192     }
193 
194     /**
195      * find message by id.
196      * @param pId the message Id.
197      * @return the message
198      * @throws ArduinoParserException on error
199      */
200     ArduinoMessage findMessageById(final String pId) throws ArduinoParserException {
201         /* Loop through the list */
202         for (ArduinoNode myNode : theNodes) {
203             final ArduinoMessage myMessage = myNode.findMessageById(pId);
204             if (myMessage != null) {
205                 return myMessage;
206             }
207         }
208 
209         /* Not found */
210         throw new ArduinoParserException("Unknown id: ", pId);
211     }
212 
213     /**
214      * find signal by Id and name.
215      * @param pId the message Id.
216      * @param pName the signal name
217      * @return the signal
218      * @throws ArduinoParserException on error
219      */
220     ArduinoSignal findSignalByIdAndName(final String pId,
221                                         final String pName) throws ArduinoParserException {
222         /* Find the message */
223         final ArduinoMessage myMessage = findMessageById(pId);
224 
225         /* Find the signal */
226         return myMessage.findSignalByName(pName);
227     }
228 
229     /**
230      * find attribute by name.
231      * @param pName the signal name
232      * @return the attribute
233      * @throws ArduinoParserException on error
234      */
235     ArduinoAttribute findAttributeByName(final String pName) throws ArduinoParserException {
236         /* Find the attribute */
237         final ArduinoAttribute myAttr = theCoreAttributes.getAttributeForName(pName);
238         if (myAttr == null) {
239             throw new ArduinoParserException("Unknown attribute: ", pName);
240         }
241         return myAttr;
242     }
243 
244     /**
245      * Obtain the comment for an object (if any).
246      * @param pObject the object
247      * @return the comment (or null)
248      */
249     public String getCommentForObject(final ArduinoNamedObject pObject) {
250         return theComments.getCommentForObject(pObject);
251     }
252 
253     /**
254      * Store the comment for an object.
255      * @param pObject the object
256      * @param pComment the comment
257      */
258     void storeCommentForObject(final ArduinoNamedObject pObject,
259                                final String pComment) {
260         theComments.storeCommentForObject(pObject, pComment);
261     }
262 
263     /**
264      * Store the attribute.
265      * @param pAttr the attribute
266      * @throws ArduinoException on error
267      */
268     void storeAttribute(final ArduinoAttribute pAttr) throws ArduinoException {
269         theCoreAttributes.storeAttribute(pAttr);
270     }
271 
272     /**
273      * Parse system.
274      * @param pName the system name
275      * @param pSystemDef the system representation
276      * @return the system
277      * @throws ArduinoException on error
278      */
279     static ArduinoSystem parseSystem(final String pName,
280                                      final String pSystemDef) throws ArduinoException {
281         /* Marker is first token in header */
282         final String myMarker = ArduinoParser.nextToken(pSystemDef);
283         final String myNodes = ArduinoParser.stripToken(pSystemDef, myMarker);
284         if (!myMarker.equals(ArduinoNode.MARKER + ArduinoChar.COLON)) {
285             throw new ArduinoException("Invalid marker", pSystemDef);
286         }
287 
288         /* Create the system */
289         final ArduinoSysteminoSystem.html#ArduinoSystem">ArduinoSystem mySystem = new ArduinoSystem(pName);
290 
291         /* Parse the nodes */
292         mySystem.parseNodes(myNodes);
293 
294         /* Return the parsed system */
295         return mySystem;
296     }
297 
298     @Override
299     public boolean equals(final Object pThat) {
300         /* Handle trivial cases */
301         if (pThat == this) {
302             return true;
303         } else if (!(pThat instanceof ArduinoSystem)) {
304             return false;
305         }
306 
307         /* Access correctly */
308         final ArduinoSystem./../net/sourceforge/jarduino/message/ArduinoSystem.html#ArduinoSystem">ArduinoSystem myThat = (ArduinoSystem) pThat;
309 
310         /* Check name */
311         return theName.equals(myThat.getName());
312     }
313 
314     @Override
315     public int hashCode() {
316         return Objects.hashCode(theName);
317     }
318 
319     @Override
320     public String toString() {
321         return theName;
322     }
323 }