MessageDefinitionParser.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Google Inc.
00003  * 
00004  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
00005  * use this file except in compliance with the License. You may obtain a copy of
00006  * the License at
00007  * 
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
00013  * License for the specific language governing permissions and limitations under
00014  * the License.
00015  */
00016 
00017 package org.ros.internal.message.definition;
00018 
00019 import com.google.common.base.Preconditions;
00020 
00021 import org.ros.exception.RosMessageRuntimeException;
00022 import org.ros.internal.message.field.PrimitiveFieldType;
00023 
00024 import java.io.BufferedReader;
00025 import java.io.IOException;
00026 import java.io.StringReader;
00027 
00034 public class MessageDefinitionParser {
00035 
00036   private final MessageDefinitionVisitor visitor;
00037 
00038   public interface MessageDefinitionVisitor {
00049     void constantValue(String type, String name, String value);
00050 
00059     void variableValue(String type, String name);
00060 
00071     void variableList(String type, int size, String name);
00072   }
00073 
00079   public MessageDefinitionParser(MessageDefinitionVisitor visitor) {
00080     this.visitor = visitor;
00081   }
00082 
00091   public void parse(String messageType, String messageDefinition) {
00092     Preconditions.checkNotNull(messageType);
00093     Preconditions.checkNotNull(messageDefinition);
00094     BufferedReader reader = new BufferedReader(new StringReader(messageDefinition));
00095     String line;
00096     try {
00097       while (true) {
00098         line = reader.readLine();
00099         if (line == null) {
00100           break;
00101         }
00102         line = line.trim();
00103         if (line.startsWith("#")) {
00104           continue;
00105         }
00106         if (line.length() > 0) {
00107           parseField(messageType, line);
00108         }
00109       }
00110     } catch (IOException e) {
00111       throw new RosMessageRuntimeException(e);
00112     }
00113   }
00114 
00115   private void parseField(String messageType, String fieldDefinition) {
00116     // TODO(damonkohler): Regex input validation.
00117     String[] typeAndName = fieldDefinition.split("\\s+", 2);
00118     Preconditions.checkState(typeAndName.length == 2,
00119         String.format("Invalid field definition: \"%s\"", fieldDefinition));
00120     String type = typeAndName[0];
00121     String name = typeAndName[1];
00122     String value = null;
00123     if (name.contains("=") && (!name.contains("#") || name.indexOf('#') > name.indexOf('='))) {
00124       String[] nameAndValue = name.split("=", 2);
00125       name = nameAndValue[0].trim();
00126       value = nameAndValue[1].trim();
00127     } else if (name.contains("#")) {
00128       // Stripping comments from constants is deferred until we also know the
00129       // type since strings are handled differently.
00130       Preconditions.checkState(!name.startsWith("#"), String.format(
00131           "Fields must define a name. Field definition in %s was: \"%s\"", messageType,
00132           fieldDefinition));
00133       name = name.substring(0, name.indexOf('#'));
00134       name = name.trim();
00135     }
00136     boolean array = false;
00137     int size = -1;
00138     if (type.endsWith("]")) {
00139       int leftBracketIndex = type.lastIndexOf('[');
00140       int rightBracketIndex = type.lastIndexOf(']');
00141       array = true;
00142       if (rightBracketIndex - leftBracketIndex > 1) {
00143         size = Integer.parseInt(type.substring(leftBracketIndex + 1, rightBracketIndex));
00144       }
00145       type = type.substring(0, leftBracketIndex);
00146     }
00147     if (type.equals("Header")) {
00148       // The header field is treated as though it were a built-in and silently
00149       // expanded to "std_msgs/Header."
00150       Preconditions.checkState(name.equals("header"), "Header field must be named \"header.\"");
00151       type = "std_msgs/Header";
00152     } else if (!PrimitiveFieldType.existsFor(type) && !type.contains("/")) {
00153       // Handle package relative message names.
00154       type = messageType.substring(0, messageType.lastIndexOf('/') + 1) + type;
00155     }
00156     if (value != null) {
00157       if (array) {
00158         // TODO(damonkohler): Handle array constants?
00159         throw new UnsupportedOperationException("Array constants are not supported.");
00160       }
00161       // Comments inline with string constants are treated as data.
00162       if (!type.equals(PrimitiveFieldType.STRING.getName()) && value.contains("#")) {
00163         Preconditions.checkState(!value.startsWith("#"), "Constants must define a value.");
00164         value = value.substring(0, value.indexOf('#'));
00165         value = value.trim();
00166       }
00167       visitor.constantValue(type, name, value);
00168     } else {
00169       if (array) {
00170         visitor.variableList(type, size, name);
00171       } else {
00172         visitor.variableValue(type, name);
00173       }
00174     }
00175   }
00176 }


rosjava_bootstrap
Author(s): Daniel Stonier , Damon Kohler
autogenerated on Fri Aug 28 2015 12:41:44