blob: 4a44ba0885f2f1e21b6291778a5aee136f3ff4df [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.pig.impl.util;
import java.io.IOException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.pig.LoadCaster;
import org.apache.pig.PigWarning;
import org.apache.pig.ResourceSchema.ResourceFieldSchema;
import org.apache.pig.data.DataByteArray;
import org.apache.pig.data.DataType;
public class CastUtils {
private static Integer mMaxInt = Integer.valueOf(Integer.MAX_VALUE);
private static Long mMaxLong = Long.valueOf(Long.MAX_VALUE);
protected static final Log mLog = LogFactory.getLog(CastUtils.class);
/**
*
* @param caster LoadCaster to be used to convert the bytes into a field.
* @param bytes
* @param fieldSchema schema of Bag or Tuple; pass in null if a simple type.
* @param dataType type from DataType
* @return converted object.
* @throws IOException
*/
public static Object convertToType(LoadCaster caster, byte[] bytes,
ResourceFieldSchema fieldSchema, byte dataType) throws IOException {
switch (dataType) {
case (DataType.BAG): return caster.bytesToBag(bytes, fieldSchema);
case (DataType.BYTEARRAY): return new DataByteArray(bytes);
case (DataType.CHARARRAY): return caster.bytesToCharArray(bytes);
case (DataType.DOUBLE): return caster.bytesToDouble(bytes);
case (DataType.FLOAT): return caster.bytesToFloat(bytes);
case (DataType.INTEGER): return caster.bytesToInteger(bytes);
case (DataType.BIGINTEGER): return caster.bytesToBigInteger(bytes);
case (DataType.BIGDECIMAL): return caster.bytesToBigDecimal(bytes);
case (DataType.LONG): return caster.bytesToLong(bytes);
case (DataType.BOOLEAN): return caster.bytesToBoolean(bytes);
case (DataType.DATETIME): return caster.bytesToDateTime(bytes);
case (DataType.MAP): return caster.bytesToMap(bytes, fieldSchema);
case (DataType.TUPLE): return caster.bytesToTuple(bytes, fieldSchema);
default: throw new IOException("Unknown type " + dataType);
}
}
public static Double stringToDouble(String str) {
if (str == null) {
return null;
} else {
try {
return Double.parseDouble(str);
} catch (NumberFormatException e) {
LogUtils
.warn(
CastUtils.class,
"Unable to interpret value "
+ str
+ " in field being "
+ "converted to double, caught NumberFormatException <"
+ e.getMessage() + "> field discarded",
PigWarning.FIELD_DISCARDED_TYPE_CONVERSION_FAILED,
mLog);
return null;
}
}
}
public static Float stringToFloat(String str) {
if (str == null) {
return null;
} else {
try {
return Float.parseFloat(str);
} catch (NumberFormatException e) {
LogUtils
.warn(
CastUtils.class,
"Unable to interpret value "
+ str
+ " in field being "
+ "converted to float, caught NumberFormatException <"
+ e.getMessage() + "> field discarded",
PigWarning.FIELD_DISCARDED_TYPE_CONVERSION_FAILED,
mLog);
return null;
}
}
}
public static Integer stringToInteger(String str) {
if (str == null) {
return null;
} else {
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
// It's possible that this field can be interpreted as a double.
// Unfortunately Java doesn't handle this in Integer.valueOf. So
// we need to try to convert it to a double and if that works
// then
// go to an int.
try {
Double d = Double.valueOf(str);
// Need to check for an overflow error
if (d.doubleValue() > mMaxInt.doubleValue() + 1.0) {
LogUtils.warn(CastUtils.class, "Value " + d
+ " too large for integer",
PigWarning.TOO_LARGE_FOR_INT, mLog);
return null;
}
return Integer.valueOf(d.intValue());
} catch (NumberFormatException nfe2) {
LogUtils
.warn(
CastUtils.class,
"Unable to interpret value "
+ str
+ " in field being "
+ "converted to int, caught NumberFormatException <"
+ e.getMessage()
+ "> field discarded",
PigWarning.FIELD_DISCARDED_TYPE_CONVERSION_FAILED,
mLog);
return null;
}
}
}
}
public static Long stringToLong(String str) {
if (str == null) {
return null;
} else {
try {
return Long.parseLong(str);
} catch (NumberFormatException e) {
// It's possible that this field can be interpreted as a double.
// Unfortunately Java doesn't handle this in Long.valueOf. So
// we need to try to convert it to a double and if that works
// then
// go to an long.
try {
Double d = Double.valueOf(str);
// Need to check for an overflow error
if (d.doubleValue() > mMaxLong.doubleValue() + 1.0) {
LogUtils.warn(CastUtils.class, "Value " + d
+ " too large for long",
PigWarning.TOO_LARGE_FOR_INT, mLog);
return null;
}
return Long.valueOf(d.longValue());
} catch (NumberFormatException nfe2) {
LogUtils
.warn(
CastUtils.class,
"Unable to interpret value "
+ str
+ " in field being "
+ "converted to long, caught NumberFormatException <"
+ nfe2.getMessage()
+ "> field discarded",
PigWarning.FIELD_DISCARDED_TYPE_CONVERSION_FAILED,
mLog);
return null;
}
}
}
}
public static Boolean stringToBoolean(String str) {
if (str == null) {
return null;
} else {
if (str.equalsIgnoreCase("true")) {
return Boolean.TRUE;
} else if (str.equalsIgnoreCase("false")) {
return Boolean.FALSE;
} else {
return null;
}
}
}
}