## ---------------------------------------------------------------------------- ## CERTI - HLA RunTime Infrastructure ## Copyright (C) 2002-2005 ONERA ## ## This program is free software ; you can redistribute it and/or ## modify it under the terms of the GNU Lesser General Public License ## as published by the Free Software Foundation ; either version 2 of ## the License, or (at your option) Any later version. ## ## This program 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 ## Lesser General Public License for more details. ## ## You should have received a copy of the GNU Lesser General Public ## License along with this program ; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ## USA ## ## $Id: GenMsgJava.py,v 1.3 2010/03/11 12:13:27 erk Exp $ ## ---------------------------------------------------------------------------- """ The CERTI Message Generator. Java Backend Generator """ import GenMsgAST import GenMsgBase class JavaGenerator(GenMsgBase.CodeGenerator): """ This is a Java generator for C{MessageAST}. """ def generatorName(cls): return "Java" generatorName = classmethod(generatorName) def __init__(self, MessageAST): super(JavaGenerator, self).__init__(MessageAST, "//") # Message builtin type to Java type # Note that java integer type are ALL signed: # http://java.sun.com/docs/books/tutorial/java/nutsandbolts/datatypes.html self.builtinTypeMap = {'onoff': 'boolean', 'bool': 'boolean', 'string': 'String', 'byte': 'byte', 'int8': 'byte', 'uint8': 'byte', 'int16': 'short', 'uint16': 'short', 'int32': 'int', 'uint32': 'int', 'int64': 'long', 'uint64': 'long', 'float': 'float', 'double': 'double', 'Tag': 'byte[]', 'RepeatedExtent': 'List', 'SuppliedParameters': 'SuppliedParameters', #'FederateHandleSet': 'FederateHandleSet', 'Regions': 'List', 'AttributeHandleValuePairSet': 'CertiHandleValuePairCollection', 'ParameterHandleValuePairSet': 'CertiHandleValuePairCollection', 'RepeatedAttributeHandle': 'AttributeHandleSet', 'RepeatedFederateHandle': 'FederateHandleSet', 'ObjectHandle':'long', 'AttributeHandle':'short', 'FederateHandle':'short', 'OrderType':'long', 'TransportType':'long', 'InteractionClassHandle':"long", 'SpaceHandle':"long", 'ObjectClassHandle':"long", 'RegionHandle':'long', 'ResignAction':'int', 'ParameterHandle':"short", 'DimensionHandle':"long"} self.serializeTypeMap = {'onoff': 'messageBuffer.write(%s);', 'bool': 'messageBuffer.write(%s);', 'string': 'messageBuffer.write(%s);', 'byte': 'messageBuffer.write(%s);', 'int8': 'messageBuffer.write(%s);', 'uint8': 'messageBuffer.write(%s);', 'int16': ' messageBuffer.write(%s);', 'uint16': 'messageBuffer.write(%s);', 'int32': 'messageBuffer.write(%s);', 'uint32': 'messageBuffer.write(%s);', 'int64': 'messageBuffer.write(%s);', 'uint64': 'messageBuffer.write(%s);', 'float': 'messageBuffer.write(%s);', 'double': 'messageBuffer.write(%s);', 'Tag': 'messageBuffer.writeBytesWithSize(%s);', 'RepeatedAttributeHandle': 'messageBuffer.write(%s);', 'SuppliedAttributes': 'messageBuffer.write(%s);', 'SuppliedParameters': 'messageBuffer.write(%s);', 'RepeatedFederateHandle': 'messageBuffer.write(%s);', 'LogicalTimeInterval':'messageBuffer.write(%s);', 'RepeatedExtent': 'messageBuffer.write(%s);', 'Regions': 'messageBuffer.writeRegions(%s);', 'AttributeHandleValuePairSet': 'messageBuffer.write(%s);', 'ParameterHandleValuePairSet': 'messageBuffer.write(%s);', 'EventRetractionHandle': 'messageBuffer.write(%s);', 'OrderType':'messageBuffer.write(%s);', 'TransportType':'messageBuffer.write(%s);', 'ObjectHandle':'messageBuffer.write(%s);', 'ResignAction':'messageBuffer.write(%s);', 'ParameterHandle':'messageBuffer.write(%s);', 'DimensionHandle':'messageBuffer.write(%s);'} self.deserializeTypeMap = {'onoff': '%s = messageBuffer.readBoolean();', 'bool': '%s = messageBuffer.readBoolean();', 'string': '%s = messageBuffer.readString();', 'byte': '%s = messageBuffer.readByte();', 'int8': '%s = messageBuffer.read_int8();', 'uint8': '%s = messageBuffer.read_uint8();', 'int16': '%s = messageBuffer.readShort();', 'uint16': '%s = messageBuffer.readShort();', 'int32': '%s = messageBuffer.readInt();', 'uint32': '%s = messageBuffer.readInt();', 'int64': '%s = messageBuffer.readLong();', 'uint64': '%s = messageBuffer.readLong();', 'float': '%s = messageBuffer.readFloat();', 'double': '%s = messageBuffer.readDouble();', 'Tag': '%s = messageBuffer.readBytesWithSize();', 'RepeatedAttributeHandle': '%s = messageBuffer.readAttributeHandleSet();', 'SuppliedAttributes': '%s = messageBuffer.readSuppliedAttributes();', 'SuppliedParameters': '%s = messageBuffer.readSuppliedParameters();', 'RepeatedFederateHandle': '%s = messageBuffer.readFederateHandleSet();', 'LogicalTimeInterval':'%s = messageBuffer.readLogicalTimeInterval();', 'RepeatedExtent': '%s = messageBuffer.readExtents();', 'Regions': '%s = messageBuffer.readRegions();', 'AttributeHandleValuePairSet': '%s = messageBuffer.readHandleValuePairCollection();', 'ParameterHandleValuePairSet': '%s = messageBuffer.readHandleValuePairCollection();', 'EventRetractionHandle': '%s = messageBuffer.readEventRetractionHandle();', 'AttributeHandle':'%s = messageBuffer.readShort();', 'FederateHandle':'%s = messageBuffer.readShort();', 'OrderType':'%s = messageBuffer.readLong();', 'TransportType':'%s = messageBuffer.readLong();', 'ObjectHandle':'%s = messageBuffer.readLong();', 'ResignAction':'%s = messageBuffer.readInt();', 'DimensionHandle':'%s = messageBuffer.readLong();', 'ParameterHandle':'%s = messageBuffer.readShort();' } def generateIncludes(self, stream): # for native in self.AST.natives: # if native.hasLanguage("Java"): # for line in native.getLanguageLines("Java"): # # we are only interested in native "include" statement # stmt = line.statement # if stmt.find("import") >= 0: # stream.write(stmt + "\n") stream.write("\n") stream.write("""import certi.communication.CertiException; import certi.communication.*; import java.util.List; import hla.rti.*; import certi.rti.impl.*; import hla.rti.*;\n\n""") def generateHeader(self, stream, factoryOnly=False): for native in self.AST.natives: if native.hasLanguage("Java"): # This an example may be it would be worth to check whether if the # refered native types are valids? for line in native.getLanguageLines("Java"): stream.write("Found native **" + line.statement + "**\n") def prepareName(self, name): upperAfterScore = lambda x:__import__('re').sub(r'_(.)', lambda y:y.group(0).upper(), x) return upperAfterScore(name.lower()).replace("_", "")[1:] def getSerializeMethodName(self, name): if name in self.serializeTypeMap.keys(): return self.serializeTypeMap[name] else: representation = self.getRepresentationFor(name) if representation: return self.getSerializeMethodName(representation) print "No serialize method name for <%s> " % name return None def getDeSerializeMethodName(self, name): if name in self.deserializeTypeMap.keys(): return self.deserializeTypeMap[name] else: representation = self.getRepresentationFor(name) if representation: return self.getDeSerializeMethodName(representation) return None def getRepresentationFor(self, name): for native in self.AST.natives: if name == native.name: representation = native.getRepresentation() if representation: return representation return name def generateBody(self, stream, factoryOnly=False): """ Generate the body. """ for msg in self.AST.messages: file = open("messages/" + self.prepareName(msg.name) + ".java", "w") file.write("""// ---------------------------------------------------------------------------- // CERTI - HLA Run Time Infrastructure // Copyright (C) 2010 Andrej Pancik // // This program is free software ; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation ; either version 2 of // the License, or (at your option) any later version. // // This program 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 // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this program ; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // ---------------------------------------------------------------------------- """) file.write("package certi.communication.messages;\n\n") self.generateIncludes(file); file.write(self.getIndent() + "public class " + self.prepareName(msg.name) + " extends CertiMessage {\n") self.indent() #DECLARATION OF FIELDS for field in msg.fields: file.write(self.getIndent() + "private ") if isinstance(field, GenMsgAST.MessageType.CombinedField): #COMBINED file.write(self.getTargetTypeName(field.typeid) + " " + field.typeid + ";\n") else: if field.qualifier == "repeated": #COLLECTION file.write(self.getTargetTypeName("Repeated" + field.typeid.name) + " " + field.name + ";\n") else: #SINGLE if field.hasDefaultValue(): file.write(self.getTargetTypeName(field.typeid.name) + " " + field.name + "=" + str(field.defaultValue) + ";\n") else: file.write(self.getTargetTypeName(field.typeid.name) + " " + field.name + ";\n") file.write("\n") #CONSTRUCTOR file.write(self.getIndent() + "public " + self.prepareName(msg.name) + "() {\n") self.indent() file.write(self.getIndent() + "super(CertiMessageType." + msg.name.upper()[2:] + ");\n") self.unIndent() file.write(self.getIndent() + "}\n\n"); #WRITING file.write(self.getIndent() + "@Override\n") file.write(self.getIndent() + "public void writeMessage(MessageBuffer messageBuffer) {\n") self.indent() file.write(self.getIndent() + "super.writeMessage(messageBuffer); //Header\n\n"); for field in msg.fields: if isinstance(field, GenMsgAST.MessageType.CombinedField): file.write(self.getIndent() + self.getSerializeMethodName(field.typeid) % field.typeid + "\n") else: if field.qualifier == "optional": file.write(self.getIndent() + "if(" +field.name + " != null){\n") self.indent() file.write(self.getIndent() + "messageBuffer.write(true);\n") file.write(self.getIndent() + self.getSerializeMethodName(field.typeid.name) % field.name + "\n") self.unIndent() file.write(self.getIndent() + "} else {\n") self.indent() file.write(self.getIndent() + "messageBuffer.write(false);\n") self.unIndent() file.write(self.getIndent() + "}\n") elif field.qualifier == "repeated": file.write(self.getIndent() + self.getSerializeMethodName("Repeated" + field.typeid.name) % field.name + "\n") else: file.write(self.getIndent() + self.getSerializeMethodName(field.typeid.name) % field.name + "\n") self.unIndent() file.write(self.getIndent() + "}\n\n"); file.write(self.getIndent() + "@Override\n") file.write(self.getIndent() + "public void readMessage(MessageBuffer messageBuffer) throws CertiException {\n") self.indent() file.write(self.getIndent() + "super.readMessage(messageBuffer); //Header \n\n"); for field in msg.fields: if isinstance(field, GenMsgAST.MessageType.CombinedField): file.write(self.getIndent() + self.getDeSerializeMethodName(field.typeid) % field.typeid + "\n") else: if field.qualifier == "optional": file.write(self.getIndent() + "boolean has" + field.name[0:1].upper() + field.name[1:] + " = messageBuffer.readBoolean();\n") file.write(self.getIndent() + "if(has" + field.name[0:1].upper() + field.name[1:] + "){\n") self.indent() file.write(self.getIndent() + self.getDeSerializeMethodName(field.typeid.name) % field.name + "\n") self.unIndent() file.write(self.getIndent() + "}\n") elif field.qualifier == "repeated": file.write(self.getIndent() + self.getDeSerializeMethodName("Repeated" + field.typeid.name) % field.name + "\n") else: file.write(self.getIndent() + self.getDeSerializeMethodName(field.typeid.name) % field.name + "\n") self.unIndent() file.write(self.getIndent() + "}\n\n"); #SERIALIZE file.write(self.getIndent() + "@Override\n") file.write(self.getIndent() + "public String toString() {\n") self.indent() file.write(self.getIndent() + "return (super.toString()"); for field in msg.fields: if isinstance(field, GenMsgAST.MessageType.CombinedField): file.write(" + \", " + field.typeid + ": \" + " + field.typeid) else: file.write(" + \", " + field.name + ": \" + " + field.name) file.write(");\n") self.unIndent() file.write(self.getIndent() + "}\n\n"); #GETTERS for field in msg.fields: # Combined field and "plain" field must not be treated the same way if not isinstance(field, GenMsgAST.MessageType.CombinedField): if field.qualifier == "repeated": file.write(self.getIndent() + "public " + self.getTargetTypeName("Repeated"+field.typeid.name) + " get" + field.name[0].capitalize() + field.name[1:] + "() {\n") self.indent() file.write(self.getIndent() + "return " + field.name + ";\n") self.unIndent() file.write(self.getIndent() + "}\n\n") else: file.write(self.getIndent() + "public " + self.getTargetTypeName(field.typeid.name) + " get" + field.name[0].capitalize() + field.name[1:] + "() {\n") self.indent() file.write(self.getIndent() + "return " + field.name + ";\n") self.unIndent() file.write(self.getIndent() + "}\n\n") #SETTERS for field in msg.fields: # Combined field and "plain" field must not be treated the same way if not isinstance(field, GenMsgAST.MessageType.CombinedField): if field.qualifier == "repeated": file.write(self.getIndent() + "public void set" + field.name[0].capitalize() + field.name[1:] + "(" + self.getTargetTypeName("Repeated"+field.typeid.name) + " new" + field.name[0].capitalize() + field.name[1:] + ") {\n"); self.indent() file.write(self.getIndent() + "this." + field.name + " = new" + field.name[0].capitalize() + field.name[1:] + ";\n") self.unIndent() file.write(self.getIndent() + "}\n\n") else: file.write(self.getIndent() + "public void set" + field.name[0].capitalize() + field.name[1:] + "(" + self.getTargetTypeName(field.typeid.name) + " new" + field.name[0].capitalize() + field.name[1:] + ") {\n"); self.indent() file.write(self.getIndent() + "this." + field.name + " = new" + field.name[0].capitalize() + field.name[1:] + ";\n") self.unIndent() file.write(self.getIndent() + "}\n\n") file.write("}\n\n") self.unIndent()