Java tutorial
/** * Licensed 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.jboss.loom.utils; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Collection; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import org.apache.commons.io.DirectoryWalker; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.FileFilterUtils; import org.apache.commons.io.filefilter.IOFileFilter; import org.apache.commons.io.filefilter.NameFileFilter; import org.apache.commons.lang.StringUtils; import org.jboss.loom.ex.CliScriptException; import org.jboss.loom.ex.CopyException; import org.jboss.loom.ex.MigrationException; import org.jboss.loom.migrators.Origin; import org.jboss.loom.spi.IConfigFragment; import org.jboss.loom.tools.report.Reporter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Global utils class. * * @author Roman Jakubco */ public class Utils { private static final Logger log = LoggerFactory.getLogger(Utils.class); /** * Prints app help. */ public static void writeHelp() { System.out.println(); System.out.println(" JBoss configuration migration tool for AS 5 / EAP 5 -> AS 7 / EAP 6 / WildFly 8"); System.out.println(); System.out.println(" Usage:"); System.out.println(); System.out.println(" java -jar AsMigrator.jar [<option>, ...] [as5.dir=]<as5.dir> [as7.dir=]<as7.dir>"); System.out.println(); System.out.println( " <as5.dir> is expected to contain path to AS 5 or EAP 5 home directory, i.e. the one with server/ subdirectory."); System.out.println(); System.out.println( " <as7.dir> is expected to contain path to AS 7 or EAP 6 home directory, i.e. the one with jboss-modules.jar."); System.out.println(); System.out.println(" Options:"); System.out.println(); System.out.println(" as5.profile=<name>"); System.out.println(" Path to AS 5 profile."); System.out.println(" Default: \"default\""); System.out.println(); System.out.println(" as7.confPath=<path> "); System.out.println(" Path to AS 7 config file."); System.out.println(" Default: \"standalone/configuration/standalone.xml\""); System.out.println(); System.out.println(" conf.<module>.<property>=<value> := Module-specific options."); System.out.println(" <module> := Name of one of modules. E.g. datasource, jaas, security, ..."); System.out.println(" <property> := Name of the property to set. Specific per module. " + "May occur multiple times."); System.out.println(); } /** * Searches a file of given name under given directory tree. * @throws CopyException if nothing found. */ public static Collection<File> searchForFile(String fileName, File dir) throws FileNotFoundException { IOFileFilter nff = new NameFileFilter(fileName); Collection<File> found = FileUtils.listFiles(dir, nff, FileFilterUtils.trueFileFilter()); if (found.isEmpty()) { throw new FileNotFoundException("File '" + fileName + "' was not found in " + dir.getAbsolutePath()); } return found; } /** * Searches a file of given name under given directory tree. * @throws CopyException if nothing found. */ public static List<File> searchForFileOrDir(final String name, final File dir) throws IOException { List<File> found = new DirectoryWalker() { @Override protected boolean handleDirectory(File directory, int depth, Collection results) throws IOException { if (directory.getName().equals(name)) results.add(directory); return true; } @Override protected void handleFile(File file, int depth, Collection results) throws IOException { if (file.getName().equals(name)) results.add(file); } public List<File> search() throws IOException { List<File> found = new LinkedList(); try { this.walk(dir, found); } catch (IOException ex) { throw new IOException("Failed traversing directory '" + dir.getAbsolutePath() + "' when looking for '" + name + "'"); } return found; } }.search(); if (found.isEmpty()) { throw new FileNotFoundException("File '" + name + "' was not found in " + dir.getAbsolutePath()); } return found; } /** * Builds up a File object with path consisting of given components. */ public static File createPath(String parent, String child, String... more) { return createPath(new File(parent), child, more); } public static File createPath(File parent, String child, String... more) { File file = new File(parent, child); for (String component : more) { file = new File(file, component); } return file; } /** * Missing from Commons IO's FileUtils... */ public static void copyFileOrDirectory(File src, File dest) throws IOException { if (src.isFile()) FileUtils.copyFile(src, dest); else if (src.isDirectory()) FileUtils.copyDirectory(src, dest); else throw new UnsupportedOperationException("Can only copy file or directory. Not this: " + src.getPath()); } // ======= Lang utils ====== // /** * Finds a subclass of given class in current stacktrace. * Returns null if not found. */ public static <T> Class<? extends T> findSubclassInStackTrace(Class<T> parentClass) { // 0 - Thread.getStackTrace(). // 1 - This method. // 2 - Whatever called this method. return findSubclassInStackTrace(parentClass, Thread.currentThread().getStackTrace(), 2); } /** * Finds a subclass of given $parentClass in given $stackTrace, skipping $skip levels. * Returns null if not found. */ public static <T> Class<? extends T> findSubclassInStackTrace(Class<T> parentClass, StackTraceElement[] stackTrace, int skip) { //for( StackTraceElement call : stackTrace) { for (int i = skip; i < stackTrace.length; i++) { StackTraceElement call = stackTrace[i]; try { Class<?> callClass = Class.forName(call.getClassName()); if (parentClass.isAssignableFrom(callClass)) return (Class<? extends T>) callClass; } catch (ClassNotFoundException ex) { Reporter.log.error("Can't load class " + call.getClassName() + ":\n " + ex.getMessage()); } } return null; } /** * Extracts all String getters properties to a map. * @see also @Property.Utils.convert*() */ public static Map<String, String> describeBean(IConfigFragment bean) { Map<String, String> ret = new LinkedHashMap(); Method[] methods = bean.getClass().getMethods(); for (Method method : methods) { boolean get = false; String name = method.getName(); // Only use getters which return String. if (method.getParameterTypes().length != 0) continue; if (!method.getReturnType().equals(String.class)) continue; if (name.startsWith("get")) get = true; if (!(get || name.startsWith("is"))) continue; // Remove "get" or "is". name = name.substring(get ? 3 : 2); // Uncapitalize, unless it's getDLQJNDIName. if (name.length() > 1 && !Character.isUpperCase(name.charAt(2))) name = StringUtils.uncapitalize(name); try { ret.put(name, (String) method.invoke(bean)); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { log.warn("Failed extracting property from " + bean.getClass().getSimpleName() + ":\n " + ex.getMessage(), ex); } } return ret; } /** * Throws a formatted message (name + errMsg) if string is null or empty. */ public static void throwIfBlank(String string, String errMsg, String name) throws CliScriptException { if ((string == null) || (string.isEmpty())) { throw new CliScriptException(name + errMsg); } } /** * Returns null for empty strings. */ public static String nullIfEmpty(String str) { return str == null ? null : (str.isEmpty() ? null : str); } public static Properties mapToProperties(Map<String, String> map) { Properties props = new Properties(); Set<Map.Entry<String, String>> entries = map.entrySet(); for (Map.Entry<String, String> entry : entries) { props.put(entry.getKey(), entry.getValue()); } return props; } public static <T extends Object> void validate(T object) throws MigrationException { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); Set<ConstraintViolation<T>> valRes = validator.validate(object); if (!valRes.isEmpty()) { StringBuilder sb = new StringBuilder("Validation failed for: "); if (object instanceof Origin.Wise) sb.append(((Origin.Wise) object).getOrigin()); else sb.append(object); for (ConstraintViolation<T> fail : valRes) { sb.append("\n ").append(fail.getPropertyPath()).append(" ").append(fail.getMessage()); } throw new MigrationException(sb.toString()); } }// validate() public static Throwable getRootCause(Throwable ex) { Throwable cause; do { cause = ex.getCause(); if (cause == null) return ex; ex = cause; } while (true); // Can exceptions ever create a loop? } }// class