// Copyright (C) 2011-2012 CRS4. // // This file is part of Seal. // // Seal is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation, either version 3 of the License, or (at your option) // any later version. // // Seal is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License along // with Seal. If not, see <http://www.gnu.org/licenses/>. package it.crs4.seal.common; import org.apache.hadoop.conf.Configuration; import org.apache.commons.logging.Log; import org.apache.hadoop.mapreduce.TaskAttemptContext; import org.apache.hadoop.mapreduce.TaskAttemptID; public class Utils { /** * Offset by which Sanger-style ASCII-encoded quality scores are shifted. */ public static final int SANGER_OFFSET = 33; /** * Maximum encodable quality score for Sanger Phred+33 encoded base qualities. */ public static final int SANGER_MAX = 62; /** * Offset by which Illumina-style ASCII-encoded quality scores are shifted. */ public static final int ILLUMINA_OFFSET = 64; /** * Maximum encodable quality score for Illumina Phred+64 encoded base qualities. */ public static final int ILLUMINA_MAX = 62; private Utils() {} // no instantiation /** * Given a number of parameters, return the first that is not null. * If all parameters are null then the result is null. */ @SuppressWarnings("unchecked") public static <T extends Object> T firstNonNull(T... objects) { for (T o: objects) { if (o != null) return o; } return null; } /** * Warn the user that he's using a deprecated property. * If newProperty is provided, the message will suggest to the user to substitute uses * of the deprecatedProperty with the new one. */ public static void deprecationWarning(Log log, String deprecatedProperty, String newProperty) { log.warn("Your configuration is using the deprecated property " + deprecatedProperty); if (newProperty == null) log.warn("You should update your configuration to avoid using it. See the documentation for details."); else log.warn("You should update your configuration to replace it with " + newProperty + ". See the documentation for details."); } /** * Check whether a deprecated property is used, and if so emit a warning. * @param deprecatedProperty The name of the deprecated property. * @param newProperty The name of the property that replaces the deprecated one, if any, * to write a suggestion to the user. */ public static void checkDeprecatedProp(Configuration conf, Log log, String deprecatedProperty, String newProperty) { if (conf.get(deprecatedProperty) != null) deprecationWarning(log, deprecatedProperty, newProperty); } /** * Substitute any characters to be avoided in a file name with '_'. */ public static String sanitizeFilename(String name) { if (name.isEmpty()) throw new IllegalArgumentException("Empty file name!"); // replace all non-word characters (a word character is: [a-zA-Z_0-9]) except '.' and '-' return name.replaceAll("[\\W&&[^.-]]", "_"); } /** * Hide the version-agnostic way we instantiate a TaskAttemptContext. * * The shift from Hadoop 1 to Hadoop 2 has changed TaskAttemptContext from * a class to an interface. This creates an issue for us as we'd like to * support both versions. To support both versions, we instantiate a * TaskAttemptContext through reflection and hide the mess in this method. */ public static TaskAttemptContext getTaskAttemptContext(Configuration conf) { final String[] knownImplementations = new String[] { "org.apache.hadoop.mapreduce.task.TaskAttemptContextImpl", "org.apache.hadoop.mapreduce.TaskAttemptContext" }; for (String name: knownImplementations) { TaskAttemptContext tac = createTACImplementation(name, conf); if (tac != null) return tac; // else, try again } // If we're here, it means we couldn't instantiate a TaskAttemptContext. // Only only option now is to throw an exception throw new RuntimeException("It seems this software isn't compatible with your\n" + " version of Hadoop. Please file a bug report. Message:\n" + "Couldn't instantiate a TaskAttemptContext"); } private static TaskAttemptContext createTACImplementation(String fullName, Configuration conf) { try { return (TaskAttemptContext) Class.forName(fullName). getConstructor(Configuration.class, TaskAttemptID.class). newInstance(conf, new TaskAttemptID()); } catch (ClassNotFoundException e) { } catch (NoSuchMethodException e) { } catch (Exception e) { System.err.println("WARNING! Couldn't instantiate " + fullName + " though we found it. Exception: " + e); } return null; } }