From a7199062bc9d4c10885f32fe9272ccc97575f16b Mon Sep 17 00:00:00 2001 From: "Hiram R. Chirino" Date: Wed, 11 Mar 2009 13:26:07 +0000 Subject: [PATCH] - Enahnced the Alt java generator so that all messages implement PBMessage - classes created by an enum can now be queried by the associated enum value. git-svn-id: https://svn.apache.org/repos/asf/activemq/activemq-protobuf/trunk@752441 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/activemq/protobuf/PBMessage.java | 23 ++++++++ .../protobuf/compiler/AltJavaGenerator.java | 52 +++++++++++++++--- .../protobuf/compiler/EnumDescriptor.java | 55 ++++++++++++++++++- .../compiler/EnumFieldDescriptor.java | 11 +++- .../protobuf/compiler/MessageDescriptor.java | 10 ++++ .../protobuf/compiler/TypeDescriptor.java | 2 + 6 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 activemq-protobuf/src/main/java/org/apache/activemq/protobuf/PBMessage.java diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/PBMessage.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/PBMessage.java new file mode 100644 index 0000000..6996f67 --- /dev/null +++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/PBMessage.java @@ -0,0 +1,23 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.activemq.protobuf; + +public interface PBMessage { + public Bean copy(); + public boolean frozen(); + public Buffer freeze(); +} diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java index 9745f71..85024f7 100644 --- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java +++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/AltJavaGenerator.java @@ -247,8 +247,15 @@ private void generateMessageBean(MessageDescriptor m) { if( multipleFiles && m.getParent()==null ) { staticOption=""; } - - p(staticOption+"public interface " + className +" {"); + + String extendsClause = " extends org.apache.activemq.protobuf.PBMessage<"+className+"."+beanClassName+", "+className+"."+bufferClassName+">"; + for (EnumFieldDescriptor enumFeild : m.getAssociatedEnumFieldDescriptors()) { + String name = uCamel(enumFeild.getParent().getName()); + name = name+"."+name+"Creatable"; + extendsClause += ", "+name; + } + + p(staticOption+"public interface " + className + extendsClause +" {"); p(); indent(); @@ -337,6 +344,16 @@ private void generateMessageBean(MessageDescriptor m) { generateMethodClear(m); generateReadWriteExternal(m); + + for (EnumFieldDescriptor enumFeild : m.getAssociatedEnumFieldDescriptors()) { + String enumName = uCamel(enumFeild.getParent().getName()); + p("public "+enumName+" to"+enumName+"() {"); + indent(); + p("return "+enumName+"."+enumFeild.getName()+";"); + unindent(); + p("}"); + p(); + } unindent(); p("}"); @@ -425,6 +442,22 @@ private void generateMessageBean(MessageDescriptor m) { generateBufferEquals(m, bufferClassName); + p("public boolean frozen() {"); + indent(); + p("return true;"); + unindent(); + p("}"); + + for (EnumFieldDescriptor enumFeild : m.getAssociatedEnumFieldDescriptors()) { + String enumName = uCamel(enumFeild.getParent().getName()); + p("public "+enumName+" to"+enumName+"() {"); + indent(); + p("return "+enumName+"."+enumFeild.getName()+";"); + unindent(); + p("}"); + p(); + } + unindent(); p("}"); p(); @@ -1542,11 +1575,9 @@ private void generateReadWriteExternal(MessageDescriptor m) { } } - - - unindent(); p("}"); + p(); } @@ -2062,13 +2093,20 @@ private void generateEnum(EnumDescriptor ed) { String createMessage = getOption(ed.getOptions(), "java_create_message", null); if( "true".equals(createMessage) ) { - p("public Object createBean() {"); + p("public interface "+uname+"Creatable {"); + indent(); + p(""+uname+" to"+uname+"();"); + unindent(); + p("}"); + p(); + + p("public "+uname+"Creatable createBean() {"); indent(); p("switch (this) {"); indent(); for (EnumFieldDescriptor field : ed.getFields().values()) { p("case "+field.getName()+":"); - String type = constantToUCamelCase(field.getName()); + String type = field.getAssociatedType().getName(); p(" return new "+type+"."+type+"Bean();"); } p("default:"); diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/EnumDescriptor.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/EnumDescriptor.java index b392fad..3e6e195 100644 --- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/EnumDescriptor.java +++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/EnumDescriptor.java @@ -52,9 +52,56 @@ public ProtoDescriptor getProtoDescriptor() { return protoDescriptor; } + private String getOption(Map options, String optionName, String defaultValue) { + OptionDescriptor optionDescriptor = options.get(optionName); + if (optionDescriptor == null) { + return defaultValue; + } + return optionDescriptor.getValue(); + } + + private String constantToUCamelCase(String name) { + boolean upNext=true; + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < name.length(); i++) { + char c = name.charAt(i); + if( Character.isJavaIdentifierPart(c) && Character.isLetterOrDigit(c)) { + if( upNext ) { + c = Character.toUpperCase(c); + upNext=false; + } else { + c = Character.toLowerCase(c); + } + sb.append(c); + } else { + upNext=true; + } + } + return sb.toString(); + } + public void validate(List errors) { - // TODO Auto-generated method stub - + String createMessage = getOption(getOptions(), "java_create_message", null); + if( "true".equals(createMessage) ) { + for (EnumFieldDescriptor field : getFields().values()) { + String type = constantToUCamelCase(field.getName()); + + TypeDescriptor typeDescriptor=null; + // Find the type def for that guy.. + if( parent!=null ) { + typeDescriptor = parent.getType(type); + } + if( typeDescriptor == null ) { + typeDescriptor = protoDescriptor.getType(type); + } + if( typeDescriptor == null ) { + errors.add("ENUM constant '"+field.getName()+"' did not find expected associated message: "+type); + } else { + field.associate(typeDescriptor); + typeDescriptor.associate(field); + } + } + } } public MessageDescriptor getParent() { @@ -81,5 +128,9 @@ public void setOptions(Map options) { this.options = options; } + public void associate(EnumFieldDescriptor desc) { + throw new RuntimeException("not supported."); + } + } diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/EnumFieldDescriptor.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/EnumFieldDescriptor.java index e011c9c..694492a 100644 --- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/EnumFieldDescriptor.java +++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/EnumFieldDescriptor.java @@ -21,7 +21,8 @@ public class EnumFieldDescriptor { private String name; private int value; private final EnumDescriptor parent; - + private TypeDescriptor associatedType; + public EnumFieldDescriptor(EnumDescriptor parent) { this.parent = parent; } @@ -46,4 +47,12 @@ public EnumDescriptor getParent() { return parent; } + public TypeDescriptor getAssociatedType() { + return associatedType; + } + + public void associate(TypeDescriptor associatedType) { + this.associatedType = associatedType; + } + } diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/MessageDescriptor.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/MessageDescriptor.java index e512f48..c407b44 100644 --- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/MessageDescriptor.java +++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/MessageDescriptor.java @@ -35,6 +35,8 @@ public class MessageDescriptor implements TypeDescriptor { private final ProtoDescriptor protoDescriptor; private List extendsList = new ArrayList(); private Map options = new LinkedHashMap(); + private List associatedEnumFieldDescriptors = new ArrayList(); + private final MessageDescriptor parent; private MessageDescriptor baseType; @@ -183,4 +185,12 @@ public MessageDescriptor getBaseType() { return baseType; } + public void associate(EnumFieldDescriptor desc) { + associatedEnumFieldDescriptors.add(desc); + } + + public List getAssociatedEnumFieldDescriptors() { + return associatedEnumFieldDescriptors; + } + } diff --git a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TypeDescriptor.java b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TypeDescriptor.java index e280b50..6e47738 100644 --- a/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TypeDescriptor.java +++ b/activemq-protobuf/src/main/java/org/apache/activemq/protobuf/compiler/TypeDescriptor.java @@ -25,4 +25,6 @@ public interface TypeDescriptor { public boolean isEnum(); + public void associate(EnumFieldDescriptor desc); + }