Java tutorial
/* * 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.giraph.debugger.mock; import java.math.BigDecimal; import java.text.DecimalFormat; import java.util.Set; import org.apache.commons.lang.NotImplementedException; import org.apache.giraph.aggregators.IntMaxAggregator; import org.apache.giraph.master.AggregatorBroadcast; import org.apache.giraph.utils.WritableUtils; import org.apache.hadoop.io.BooleanWritable; import org.apache.hadoop.io.ByteWritable; import org.apache.hadoop.io.DoubleWritable; import org.apache.hadoop.io.FloatWritable; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.io.Writable; /** * Utility class to help format some of the strings used in the generated unit * test. E.g., if an a float is initialized to 1.3 and we read that from * a protocolbuffer and write it again, it will be written as 1.299999.... * So we need to truncate it when we generate the unittest and this class * contains such methods. */ public class FormatHelper { /** * {@link DecimalFormat} to use when formatting decimals. */ private final DecimalFormat decimalFormat = new DecimalFormat("#.#####"); /** * A set of complex writable object, i.e., user-defined ones that are not like * IntWritable, FloatWritable, etc..used by this compute function. */ @SuppressWarnings("rawtypes") private Set<Class> complexWritables; /** * Default constructor. */ public FormatHelper() { } /** * @param complexWritables complex writable objects to register. */ @SuppressWarnings("rawtypes") public FormatHelper(Set<Class> complexWritables) { registerComplexWritableClassList(complexWritables); } /** * @param complexWritables complex writable objects to register. */ @SuppressWarnings("rawtypes") public void registerComplexWritableClassList(Set<Class> complexWritables) { this.complexWritables = complexWritables; } /** * Generates the line that constructs the given writable. * @param writable writable object to construct in the unit test. * @return string generating the line that constructs the given writable. */ public String formatWritable(Writable writable) { if (writable instanceof NullWritable) { return "NullWritable.get()"; } else if (writable instanceof BooleanWritable) { return String.format("new BooleanWritable(%s)", format(((BooleanWritable) writable).get())); } else if (writable instanceof ByteWritable) { return String.format("new ByteWritable(%s)", format(((ByteWritable) writable).get())); } else if (writable instanceof IntWritable) { return String.format("new IntWritable(%s)", format(((IntWritable) writable).get())); } else if (writable instanceof LongWritable) { return String.format("new LongWritable(%s)", format(((LongWritable) writable).get())); } else if (writable instanceof FloatWritable) { return String.format("new FloatWritable(%s)", format(((FloatWritable) writable).get())); } else if (writable instanceof DoubleWritable) { return String.format("new DoubleWritable(%s)", format(((DoubleWritable) writable).get())); } else if (writable instanceof Text) { return String.format("new Text(%s)", ((Text) writable).toString()); } else { if (complexWritables != null) { complexWritables.add(writable.getClass()); } String str = toByteArrayString(WritableUtils.writeToByteArray(writable)); return String.format("(%s)read%sFromByteArray(new byte[] {%s})", writable.getClass().getSimpleName(), writable.getClass().getSimpleName(), str); } } /** * Generates the line that constructs the given {@link AggregatorBroadcast}. * We only have access to the {@link Writable} object. Therefore we do not * know exactly what type of aggregator it is. So, we default to max aggregators. * For example, {@link IntWritable}, defaults to {@link IntMaxAggregator}. However * note that this is fine because the user only sees the value, not the type of * aggregator it came from. * @param writable writable object to construct in the unit test. * @return string generating the line that constructs the given writable. */ public String formatAggregatorBroadcast(Writable writable) { if (writable instanceof IntWritable) { return String.format( "new AggregatorBroadcast<IntWritable>(IntMaxAggregator.class, " + "new IntWritable(%s))", format(((IntWritable) writable).get())); } else if (writable instanceof LongWritable) { return String.format( "new AggregatorBroadcast<LongWritable>(LongMaxAggregator.class, " + "new LongWritable(%s))", format(((LongWritable) writable).get())); } else if (writable instanceof DoubleWritable) { return String.format("new AggregatorBroadcast<DoubleWritable>(DoubleMaxAggregator.class, " + "new DoubleWritable(%s))", format(((DoubleWritable) writable).get())); } else if (writable instanceof Text) { return String.format("new AggregatorBroadcast<Text>(TextAppendAggregator.class, " + "new Text(\"%s\"))", format(((Text) writable).toString())); } else { throw new NotImplementedException( "Formatting of aggregator for writable has" + " not yet been implemented."); } } /** * Generates the line that constructs the given object, which can be * an int, boolean, char, byte, short, etc. * @param input object to construct in the unit test. * @return string generating the line that constructs the given object. */ public String format(Object input) { if (input instanceof Boolean || input instanceof Byte || input instanceof Character || input instanceof Short || input instanceof Integer) { return input.toString(); } else if (input instanceof Long) { return input.toString() + "l"; } else if (input instanceof Float) { return decimalFormat.format(input) + "f"; } else if (input instanceof Double) { double val = ((Double) input).doubleValue(); if (val == Double.MAX_VALUE) { return "Double.MAX_VALUE"; } else if (val == Double.MIN_VALUE) { return "Double.MIN_VALUE"; } else { BigDecimal bd = new BigDecimal(val); return bd.toEngineeringString() + "d"; } } else { return input.toString(); } } /** * Generates a line constructing a byte array. * @param byteArray byte array to construct in the unit test. * @return string generating the line that constructs the given byte array. */ private String toByteArrayString(byte[] byteArray) { StringBuilder strBuilder = new StringBuilder(); for (int i = 0; i < byteArray.length; i++) { if (i != 0) { strBuilder.append(','); } strBuilder.append(Byte.toString(byteArray[i])); } return strBuilder.toString(); } }