| /* |
| * 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.geode.cache.query.internal.types; |
| |
| import java.io.DataInput; |
| import java.io.DataOutput; |
| import java.io.IOException; |
| import java.util.Arrays; |
| |
| import org.apache.geode.DataSerializer; |
| import org.apache.geode.cache.query.Struct; |
| import org.apache.geode.cache.query.internal.StructImpl; |
| import org.apache.geode.cache.query.types.ObjectType; |
| import org.apache.geode.cache.query.types.StructType; |
| import org.apache.geode.internal.serialization.DeserializationContext; |
| import org.apache.geode.internal.serialization.SerializationContext; |
| |
| /** |
| * Implementation of StructType |
| * |
| * @since GemFire 4.0 |
| */ |
| public class StructTypeImpl extends ObjectTypeImpl implements StructType { |
| private static final long serialVersionUID = -6368710865627039204L; |
| private String[] fieldNames; |
| private ObjectType[] fieldTypes; |
| private String[] indexAlternativeFieldNames; |
| |
| /** |
| * Empty constructor to satisfy <code>DataSerializer</code> requirements |
| */ |
| public StructTypeImpl() {} |
| |
| /** Creates a new instance of StructType */ |
| public StructTypeImpl(String[] fieldNames) { |
| this(fieldNames, null); |
| } |
| |
| public StructTypeImpl(String[] fieldNames, ObjectType[] fieldTypes) { |
| this(Struct.class, fieldNames, fieldTypes); |
| } |
| |
| public StructTypeImpl(String[] fieldNames, String[] indexAlternativeFieldNames, |
| ObjectType[] fieldTypes) { |
| this(Struct.class, fieldNames, fieldTypes); |
| this.indexAlternativeFieldNames = indexAlternativeFieldNames; |
| } |
| |
| // supply actual implementation class, handles Region.Entry case |
| // where Region.Entry acts like a Struct with extra protocol (e.g. getStatistics, etc.) |
| // By using a StructType, we get access to key and value types as well as the |
| // Region.Entry properties. |
| public StructTypeImpl(Class clazz, String[] fieldNames, ObjectType[] fieldTypes) { |
| super(clazz); |
| if (fieldNames == null) { |
| throw new IllegalArgumentException( |
| "fieldNames must not be null"); |
| } |
| this.fieldNames = fieldNames; |
| this.fieldTypes = fieldTypes == null ? new ObjectType[this.fieldNames.length] : fieldTypes; |
| for (int i = 0; i < this.fieldTypes.length; i++) { |
| if (this.fieldTypes[i] == null) { |
| this.fieldTypes[i] = TypeUtils.getObjectType(Object.class); |
| } |
| } |
| } |
| |
| |
| @Override |
| public ObjectType[] getFieldTypes() { |
| return this.fieldTypes; |
| } |
| |
| @Override |
| public String[] getFieldNames() { |
| return this.fieldNames; |
| } |
| |
| @Override |
| public int getFieldIndex(String fieldName) { |
| for (int i = 0; i < this.fieldNames.length; i++) { |
| if (this.fieldNames[i].equals(fieldName)) { |
| return i; |
| } |
| } |
| throw new IllegalArgumentException( |
| String.format("fieldName %s not found", fieldName)); |
| } |
| |
| @Override |
| public boolean equals(Object obj) { |
| if (!(obj instanceof StructTypeImpl)) |
| return false; |
| StructTypeImpl t = (StructTypeImpl) obj; |
| return (Arrays.equals(this.fieldNames, t.getFieldNames()) |
| || Arrays.equals(this.indexAlternativeFieldNames, t.getFieldNames())) |
| && Arrays.equals(getFieldTypes(), t.getFieldTypes()); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Arrays.hashCode(fieldNames) ^ Arrays.hashCode(fieldTypes); |
| } |
| |
| @Override |
| public String toString() { |
| StringBuffer sb = new StringBuffer("struct<"); |
| for (int i = 0; i < fieldNames.length; i++) { |
| if (i > 0) |
| sb.append(','); |
| sb.append(fieldNames[i] + ":" + fieldTypes[i]); |
| } |
| sb.append('>'); |
| return sb.toString(); |
| } |
| |
| @Override |
| public boolean isCollectionType() { |
| return false; |
| } |
| |
| @Override |
| public boolean isMapType() { |
| return false; |
| } |
| |
| @Override |
| public boolean isStructType() { |
| return true; |
| } |
| |
| |
| // Static Utilities |
| public static StructTypeImpl typeFromStruct(Struct s) { |
| // handle unlikely event that Struct is not a StructImpl |
| if (s instanceof StructImpl) { |
| return (StructTypeImpl) s.getStructType(); |
| } |
| return new StructTypeImpl(s.getStructType().getFieldNames(), s.getStructType().getFieldTypes()); |
| } |
| |
| @Override |
| public int getDSFID() { |
| return STRUCT_TYPE_IMPL; |
| } |
| |
| @Override |
| public void fromData(DataInput in, |
| DeserializationContext context) throws IOException, ClassNotFoundException { |
| super.fromData(in, context); |
| this.fieldNames = DataSerializer.readStringArray(in); |
| this.fieldTypes = (ObjectType[]) DataSerializer.readObjectArray(in); |
| } |
| |
| @Override |
| public void toData(DataOutput out, |
| SerializationContext context) throws IOException { |
| super.toData(out, context); |
| DataSerializer.writeStringArray(this.fieldNames, out); |
| DataSerializer.writeObjectArray(fieldTypes, out); |
| } |
| |
| } |