blob: 7fcb7b88394c83f31387a65f041375dd824f429e [file] [log] [blame]
/**
* 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.wave.pst.model;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
/**
* Wraps a {@link FieldDescriptor} to expose type-only information for
* stringtemplate.
*
* @author kalman@google.com (Benjamin Kalman)
*/
public final class Type {
private final FieldDescriptor field;
private final String templateName;
private final MessageProperties extraProperties;
private Message messageType;
public Type(FieldDescriptor field, String templateName, MessageProperties extraProperties) {
this.field = field;
this.templateName = templateName;
this.extraProperties = extraProperties;
}
/**
* Returns the type of the field as the Java type, for example:
* <ul>
* <li>org.waveprotocol.pst.examples.Example1.Person.first_name = "String"</li>
* <li>org.waveprotocol.pst.examples.Example1.Person.age = "int"</li>
* <li>org.waveprotocol.pst.examples.Example1.Person.gender = "Gender"</li>
* <li>org.waveprotocol.pst.examples.Example1.Person.address = <ul>
* <li>"AddressMessage" (if template name is "message")</li>
* <li>"AddressMessageServerImpl" (if template name is "messageServerImpl")</li></ul></li>
* </ul>
*
* @return the type of the field as the Java type
*/
public String getJavaType(boolean hasInt52Ext) {
switch (field.getJavaType()) {
case BOOLEAN:
return "boolean";
case BYTE_STRING:
return "Blob";
case DOUBLE:
return "double";
case ENUM:
return field.getEnumType().getName();
case FLOAT:
return "float";
case INT:
return "int";
case LONG:
return hasInt52Ext && extraProperties.getUseInt52() ? "double" : "long";
case MESSAGE:
return getMessage().getJavaType();
case STRING:
return "String";
default:
throw new UnsupportedOperationException("Unsupported field type " + field.getJavaType());
}
}
/**
* Returns the type of the field as the Java type capitalized, for example:
* <ul>
* <li>org.waveprotocol.pst.examples.Example1.Person.first_name = "String"</li>
* <li>org.waveprotocol.pst.examples.Example1.Person.age = "Int"</li>
* <li>org.waveprotocol.pst.examples.Example1.Person.gender = "Gender"</li>
* <li>org.waveprotocol.pst.examples.Example1.Person.address = <ul>
* <li>"AddressMessage" (if template name is "message")</li>
* <li>"AddressMessageServerImpl" (if template name is "messageServerImpl")</li></ul></li>
* </ul>
*
* @return the type of the field as the Java type
*/
public String getCapJavaType(boolean hasInt52Ext) {
return Util.capitalize(getJavaType(hasInt52Ext));
}
/**
* Returns the type of the field as the boxed Java type, for example:
* <ul>
* <li>org.waveprotocol.pst.examples.Example1.Person.first_name = "String"</li>
* <li>org.waveprotocol.pst.examples.Example1.Person.age = "Integer"</li>
* <li>org.waveprotocol.pst.examples.Example1.Person.gender = "Gender"</li>
* <li>org.waveprotocol.pst.examples.Example1.Person.address = <ul>
* <li>"AddressMessage" (if template name is "message")</li>
* <li>"AddressMessageServerImpl" (if template name is "messageServerImpl")</li></ul></li>
* </ul>
*
* @return the type of the field as a boxed Java type
*/
public String getBoxedJavaType(boolean hasInt52Ext) {
switch (field.getJavaType()) {
case BOOLEAN:
return "Boolean";
case DOUBLE:
return "Double";
case FLOAT:
return "Float";
case INT:
return "Integer";
case LONG:
return hasInt52Ext && extraProperties.getUseInt52() ? "Double" : "Long";
default:
return getJavaType(hasInt52Ext);
}
}
/**
* Gets the default value of the field (null for objects, zero, false, etc).
*
* @return the "default value" of the field
*/
public String getDefaultValue() {
switch (field.getJavaType()) {
case BOOLEAN:
return "false";
case BYTE_STRING:
return "null";
case DOUBLE:
return "0.0";
case ENUM:
return field.getEnumType().getName() + ".UNKNOWN";
case FLOAT:
return "0.0f";
case INT:
return "0";
case LONG:
return "0L";
case MESSAGE:
return "null";
case STRING:
return "null";
default:
throw new UnsupportedOperationException("Unsupported field type " + field.getJavaType());
}
}
/**
* @return this type as a message.
*/
public Message getMessage() {
if (messageType == null) {
messageType = adapt(field.getMessageType());
}
return messageType;
}
/**
* @return whether the field is a message
*/
public boolean isMessage() {
return field.getType().equals(FieldDescriptor.Type.MESSAGE);
}
/**
* @return whether the field is an enum
*/
public boolean isEnum() {
return field.getType().equals(FieldDescriptor.Type.ENUM);
}
/**
* @return whether the field is a byte string.
*/
public boolean isBlob() {
return field.getType().equals(FieldDescriptor.Type.BYTES);
}
/**
* @return whether the field type is a Java primitive
*/
public boolean isPrimitive() {
switch (field.getJavaType()) {
case BOOLEAN:
case DOUBLE:
case FLOAT:
case INT:
case LONG:
return true;
default:
return false;
}
}
private Message adapt(Descriptor d) {
return new Message(d, templateName, extraProperties);
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (o instanceof Type) {
Type t = (Type) o;
if (field.getType() == t.field.getType()) {
switch (field.getType()) {
case MESSAGE:
return field.getMessageType().equals(t.field.getMessageType());
case ENUM:
return field.getEnumType().equals(t.field.getEnumType());
default:
return true;
}
} else {
return false;
}
} else {
return false;
}
}
@Override
public int hashCode() {
switch (field.getType()) {
case MESSAGE:
return field.getMessageType().hashCode();
case ENUM:
return field.getEnumType().hashCode();
default:
return field.getType().hashCode();
}
}
}