001    // =================================================================================================
002    // Copyright 2011 Twitter, Inc.
003    // -------------------------------------------------------------------------------------------------
004    // Licensed under the Apache License, Version 2.0 (the "License");
005    // you may not use this work except in compliance with the License.
006    // You may obtain a copy of the License in the LICENSE file, or at:
007    //
008    //  http://www.apache.org/licenses/LICENSE-2.0
009    //
010    // Unless required by applicable law or agreed to in writing, software
011    // distributed under the License is distributed on an "AS IS" BASIS,
012    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013    // See the License for the specific language governing permissions and
014    // limitations under the License.
015    // =================================================================================================
016    
017    package com.twitter.common.thrift.testing;
018    
019    import com.google.common.base.Preconditions;
020    import com.google.common.collect.Maps;
021    import org.apache.thrift.TBase;
022    import org.apache.thrift.TBaseHelper;
023    import org.apache.thrift.TException;
024    import org.apache.thrift.TFieldIdEnum;
025    import org.apache.thrift.protocol.TField;
026    import org.apache.thrift.protocol.TProtocol;
027    import org.apache.thrift.protocol.TStruct;
028    import org.apache.thrift.protocol.TType;
029    
030    import java.util.Map;
031    import java.util.Map.Entry;
032    
033    /**
034     * Hand-coded thrift types for use in tests.
035     *
036     * @author John Sirois
037     */
038    public class TestThriftTypes {
039      public static class Field implements TFieldIdEnum {
040        private static final Map<Short, Field> FIELDS_BY_ID = Maps.newHashMap();
041        public static Field forId(int id) {
042          Field field = FIELDS_BY_ID.get((short) id);
043          Preconditions.checkArgument(field != null, "No Field with id: %s", id);
044          return field;
045        }
046    
047        public static final Field NAME = new Field((short) 0, "name");
048        public static final Field VALUE = new Field((short) 1, "value");
049    
050        private final short fieldId;
051        private final String fieldName;
052    
053        private Field(short fieldId, String fieldName) {
054          this.fieldId = fieldId;
055          this.fieldName = fieldName;
056          FIELDS_BY_ID.put(fieldId, this);
057        }
058    
059        @Override
060        public short getThriftFieldId() {
061          return fieldId;
062        }
063    
064        @Override
065        public String getFieldName() {
066          return fieldName;
067        }
068      }
069    
070      public static class Struct implements TBase<Struct, Field> {
071        private final Map<Field, Object> fields = Maps.newHashMap();
072    
073        public Struct() {}
074    
075        public Struct(String name, String value) {
076          fields.put(Field.NAME, name);
077          fields.put(Field.VALUE, value);
078        }
079    
080        public String getName() {
081          Object name = getFieldValue(Field.NAME);
082          return name == null ? null : (String) name;
083        }
084    
085        public String getValue() {
086          Object value = getFieldValue(Field.VALUE);
087          return value == null ? null : (String) value;
088        }
089    
090        @Override
091        public void read(TProtocol tProtocol) throws TException {
092          tProtocol.readStructBegin();
093          TField field;
094          while((field = tProtocol.readFieldBegin()).type != TType.STOP) {
095            fields.put(fieldForId(field.id), tProtocol.readString());
096            tProtocol.readFieldEnd();
097          }
098          tProtocol.readStructEnd();
099        }
100    
101        @Override
102        public void write(TProtocol tProtocol) throws TException {
103          tProtocol.writeStructBegin(new TStruct("Field"));
104          for (Entry<Field, Object> entry : fields.entrySet()) {
105            Field field = entry.getKey();
106            tProtocol.writeFieldBegin(
107                new TField(field.getFieldName(), TType.STRING, field.getThriftFieldId()));
108            tProtocol.writeString(entry.getValue().toString());
109            tProtocol.writeFieldEnd();
110          }
111          tProtocol.writeFieldStop();
112          tProtocol.writeStructEnd();
113        }
114    
115        @Override
116        public boolean isSet(Field field) {
117          return fields.containsKey(field);
118        }
119    
120        @Override
121        public Object getFieldValue(Field field) {
122          return fields.get(field);
123        }
124    
125        @Override
126        public void setFieldValue(Field field, Object o) {
127          fields.put(field, o);
128        }
129    
130        @Override
131        public TBase<Struct, Field> deepCopy() {
132          Struct struct = new Struct();
133          struct.fields.putAll(fields);
134          return struct;
135        }
136    
137        @Override
138        public int compareTo(Struct other) {
139          if (!getClass().equals(other.getClass())) {
140            return getClass().getName().compareTo(other.getClass().getName());
141          }
142    
143          int lastComparison;
144    
145          lastComparison = Integer.valueOf(fields.size()).compareTo(other.fields.size());
146          if (lastComparison != 0) {
147            return lastComparison;
148          }
149    
150          for (Map.Entry<Field, Object> entry : fields.entrySet()) {
151            Field field = entry.getKey();
152            lastComparison = Boolean.TRUE.compareTo(other.isSet(field));
153            if (lastComparison != 0) {
154              return lastComparison;
155            }
156            lastComparison = TBaseHelper.compareTo(entry.getValue(), other.getFieldValue(field));
157            if (lastComparison != 0) {
158              return lastComparison;
159            }
160          }
161          return 0;
162        }
163    
164        @Override
165        public void clear() {
166          fields.clear();
167        }
168    
169        @Override
170        public Field fieldForId(int fieldId) {
171          return Field.forId(fieldId);
172        }
173      }
174    }