001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.types;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertTrue;
022
023import org.apache.hadoop.hbase.HBaseClassTestRule;
024import org.apache.hadoop.hbase.testclassification.MiscTests;
025import org.apache.hadoop.hbase.testclassification.SmallTests;
026import org.apache.hadoop.hbase.util.Order;
027import org.apache.hadoop.hbase.util.PositionedByteRange;
028import org.apache.hadoop.hbase.util.SimplePositionedMutableByteRange;
029import org.junit.ClassRule;
030import org.junit.Test;
031import org.junit.experimental.categories.Category;
032
033@Category({MiscTests.class, SmallTests.class})
034public class TestUnion2 {
035
036  @ClassRule
037  public static final HBaseClassTestRule CLASS_RULE =
038      HBaseClassTestRule.forClass(TestUnion2.class);
039
040  /**
041   * An example <code>Union</code>
042   */
043  private static class SampleUnion1 extends Union2<Integer, String> {
044
045    private static final byte IS_INTEGER = 0x00;
046    private static final byte IS_STRING  = 0x01;
047
048    public SampleUnion1() {
049      super(new RawInteger(), new RawStringTerminated(Order.DESCENDING, "."));
050    }
051
052    @Override
053    public int skip(PositionedByteRange src) {
054      switch (src.get()) {
055        case IS_INTEGER:
056          return 1 + typeA.skip(src);
057        case IS_STRING:
058          return 1 + typeB.skip(src);
059        default:
060          throw new IllegalArgumentException("Unrecognized encoding format.");
061      }
062    }
063
064    @Override
065    public Object decode(PositionedByteRange src) {
066      switch (src.get()) {
067        case IS_INTEGER:
068          return typeA.decode(src);
069        case IS_STRING:
070          return typeB.decode(src);
071        default:
072          throw new IllegalArgumentException("Unrecognized encoding format.");
073      }
074    }
075
076    @Override
077    public int encodedLength(Object val) {
078      Integer i = null;
079      String s = null;
080      try {
081        i = (Integer) val;
082      } catch (ClassCastException e) {}
083      try {
084        s = (String) val;
085      } catch (ClassCastException e) {}
086
087      if (null != i) return 1 + typeA.encodedLength(i);
088      if (null != s) return 1 + typeB.encodedLength(s);
089      throw new IllegalArgumentException("val is not a valid member of this union.");
090    }
091
092    @Override
093    public int encode(PositionedByteRange dst, Object val) {
094      Integer i = null;
095      String s = null;
096      try {
097        i = (Integer) val;
098      } catch (ClassCastException e) {}
099      try {
100        s = (String) val;
101      } catch (ClassCastException e) {}
102
103      if (null != i) {
104        dst.put(IS_INTEGER);
105        return 1 + typeA.encode(dst, i);
106      } else if (null != s) {
107        dst.put(IS_STRING);
108        return 1 + typeB.encode(dst, s);
109      }
110      else
111        throw new IllegalArgumentException("val is not of a supported type.");
112    }
113  }
114
115  @Test
116  public void testEncodeDecode() {
117    Integer intVal = Integer.valueOf(10);
118    String strVal = "hello";
119    PositionedByteRange buff = new SimplePositionedMutableByteRange(10);
120    SampleUnion1 type = new SampleUnion1();
121
122    type.encode(buff, intVal);
123    buff.setPosition(0);
124    assertTrue(0 == intVal.compareTo(type.decodeA(buff)));
125    buff.setPosition(0);
126    type.encode(buff, strVal);
127    buff.setPosition(0);
128    assertTrue(0 == strVal.compareTo(type.decodeB(buff)));
129  }
130
131  @Test
132  public void testSkip() {
133    Integer intVal = Integer.valueOf(10);
134    String strVal = "hello";
135    PositionedByteRange buff = new SimplePositionedMutableByteRange(10);
136    SampleUnion1 type = new SampleUnion1();
137
138    int len = type.encode(buff, intVal);
139    buff.setPosition(0);
140    assertEquals(len, type.skip(buff));
141    buff.setPosition(0);
142    len = type.encode(buff, strVal);
143    buff.setPosition(0);
144    assertEquals(len, type.skip(buff));
145  }
146}