blob: a18cb757551d4863a41dbc1bf0281146a77712ed [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.hcatalog.data.schema;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.hcatalog.common.HCatException;
/**
* HCatSchema. This class is NOT thread-safe.
*/
public class HCatSchema implements Serializable {
private static final long serialVersionUID = 1L;
private final List<HCatFieldSchema> fieldSchemas;
private final Map<String, Integer> fieldPositionMap;
private final List<String> fieldNames;
/**
*
* @param fieldSchemas is now owned by HCatSchema. Any subsequent modifications
* on fieldSchemas won't get reflected in HCatSchema. Each fieldSchema's name
* in the list must be unique, otherwise throws IllegalArgumentException.
*/
public HCatSchema(final List<HCatFieldSchema> fieldSchemas) {
this.fieldSchemas = new ArrayList<HCatFieldSchema>(fieldSchemas);
int idx = 0;
fieldPositionMap = new HashMap<String, Integer>();
fieldNames = new ArrayList<String>();
for (HCatFieldSchema field : fieldSchemas) {
if (field == null)
throw new IllegalArgumentException("Field cannot be null");
String fieldName = field.getName();
if (fieldPositionMap.containsKey(fieldName))
throw new IllegalArgumentException("Field named " + fieldName +
" already exists");
fieldPositionMap.put(fieldName, idx);
fieldNames.add(fieldName);
idx++;
}
}
public void append(final HCatFieldSchema hfs) throws HCatException {
if (hfs == null)
throw new HCatException("Attempt to append null HCatFieldSchema in HCatSchema.");
String fieldName = hfs.getName();
if (fieldPositionMap.containsKey(fieldName))
throw new HCatException("Attempt to append HCatFieldSchema with already " +
"existing name: " + fieldName + ".");
this.fieldSchemas.add(hfs);
this.fieldNames.add(fieldName);
this.fieldPositionMap.put(fieldName, this.size() - 1);
}
/**
* Users are not allowed to modify the list directly, since HCatSchema
* maintains internal state. Use append/remove to modify the schema.
*/
public List<HCatFieldSchema> getFields() {
return Collections.unmodifiableList(this.fieldSchemas);
}
/**
* @param fieldName
* @return the index of field named fieldName in Schema. If field is not
* present, returns null.
*/
public Integer getPosition(String fieldName) {
return fieldPositionMap.get(fieldName);
}
public HCatFieldSchema get(String fieldName) throws HCatException {
return get(getPosition(fieldName));
}
public List<String> getFieldNames() {
return this.fieldNames;
}
public HCatFieldSchema get(int position) {
return fieldSchemas.get(position);
}
public int size() {
return fieldSchemas.size();
}
public void remove(final HCatFieldSchema hcatFieldSchema) throws HCatException {
if (!fieldSchemas.contains(hcatFieldSchema)) {
throw new HCatException("Attempt to delete a non-existent column from HCat Schema: " + hcatFieldSchema);
}
fieldSchemas.remove(hcatFieldSchema);
fieldPositionMap.remove(hcatFieldSchema);
fieldNames.remove(hcatFieldSchema.getName());
}
@Override
public String toString() {
boolean first = true;
StringBuilder sb = new StringBuilder();
for (HCatFieldSchema hfs : fieldSchemas) {
if (!first) {
sb.append(",");
} else {
first = false;
}
if (hfs.getName() != null) {
sb.append(hfs.getName());
sb.append(":");
}
sb.append(hfs.toString());
}
return sb.toString();
}
public String getSchemaAsTypeString() {
boolean first = true;
StringBuilder sb = new StringBuilder();
for (HCatFieldSchema hfs : fieldSchemas) {
if (!first) {
sb.append(",");
} else {
first = false;
}
if (hfs.getName() != null) {
sb.append(hfs.getName());
sb.append(":");
}
sb.append(hfs.getTypeString());
}
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof HCatSchema)) {
return false;
}
HCatSchema other = (HCatSchema) obj;
if (!this.getFields().equals(other.getFields())) {
return false;
}
return true;
}
@Override
public int hashCode() {
return toString().hashCode();
}
}