Java tutorial
/* * #%L * xcode-maven-plugin * %% * Copyright (C) 2012 SAP AG * %% * 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. * #L% */ package com.sap.prd.mobile.ios.mios; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.PrintStream; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.UnArchiver; import org.codehaus.plexus.archiver.manager.ArchiverManager; import org.codehaus.plexus.archiver.manager.NoSuchArchiverException; public class FileUtils { private final static String DOT = "."; public static void mkdirs(final File f) throws IOException { if (f.exists() && !f.isDirectory()) throw new IOException(String.format("'%s' does already exist but is not a directory.", f)); if (!f.exists() && !f.mkdirs()) throw new IOException("Could not create folder '" + f + "'."); } public static void deleteDirectory(final File directory) throws IOException { org.codehaus.plexus.util.FileUtils.deleteDirectory(directory); } /** * * @param parent * The parent directory * @param child * The child direcory * @return the part of the path that represents the delta between <code>parent</code> and * <code>child</code>. * @throws IllegalStateExcpetion * in case <code>child</code> is not a child of <code>parent</code>. */ public static String getDelta(File parent, File child) { final List<String> _parent = split(parent.getAbsoluteFile()); final List<String> _child = split(child.getAbsoluteFile()); if (!isChild(_parent, _child)) throw new IllegalStateException( "Child directory '" + child + "' is not a child of the base directory '" + parent + "'."); StringBuilder path = new StringBuilder(); int index = getNumberOfCommonElements(_parent, _child); for (int size = _child.size(); index < size; index++) { if (path.length() != 0) path.append(File.separator); path.append(_child.get(index)); } return path.toString(); } private static int getNumberOfCommonElements(List<String> _parent, List<String> _child) { int index = 0; for (int size = Math.min(_parent.size(), _child.size()); index < size; index++) if (!_parent.get(index).equals(_child.get(index))) break; return index; } private static List<String> split(File dir) { List<String> result = new ArrayList<String>(); do { result.add(dir.getName()); dir = dir.getParentFile(); } while (dir != null); Collections.reverse(result); return result; } /** * Get the relative path from one file to another, specifying the directory separator. If one of * the provided resources does not exist, it is assumed to be a file unless it ends with '/' or * '\'. * * Copied from http://stackoverflow.com/a/3054692/933106. * * @param target * targetPath is calculated to this file * @param base * basePath is calculated from this file * @param separator * directory separator. The platform default is not assumed so that we can test Unix * behaviour when running on Windows (for example) * @return */ public static String getRelativePath(String targetPath, String basePath, String pathSeparator) { // Normalize the paths String normalizedTargetPath = FilenameUtils.normalizeNoEndSeparator(targetPath); String normalizedBasePath = FilenameUtils.normalizeNoEndSeparator(basePath); // Undo the changes to the separators made by normalization if (pathSeparator.equals("/")) { normalizedTargetPath = FilenameUtils.separatorsToUnix(normalizedTargetPath); normalizedBasePath = FilenameUtils.separatorsToUnix(normalizedBasePath); } else if (pathSeparator.equals("\\")) { normalizedTargetPath = FilenameUtils.separatorsToWindows(normalizedTargetPath); normalizedBasePath = FilenameUtils.separatorsToWindows(normalizedBasePath); } else { throw new IllegalArgumentException("Unrecognised dir separator '" + pathSeparator + "'"); } String[] base = normalizedBasePath.split(Pattern.quote(pathSeparator)); String[] target = normalizedTargetPath.split(Pattern.quote(pathSeparator)); // First get all the common elements. Store them as a string, // and also count how many of them there are. StringBuilder common = new StringBuilder(); int commonIndex = 0; while (commonIndex < target.length && commonIndex < base.length && target[commonIndex].equals(base[commonIndex])) { common.append(target[commonIndex] + pathSeparator); commonIndex++; } if (commonIndex == 0) { // No single common path element. This most // likely indicates differing drive letters, like C: and D:. // These paths cannot be relativized. throw new PathResolutionException("No common path element found for '" + normalizedTargetPath + "' and '" + normalizedBasePath + "'"); } // The number of directories we have to backtrack depends on whether the base is a file or a dir // For example, the relative path from // // /foo/bar/baz/gg/ff to /foo/bar/baz // // ".." if ff is a file // "../.." if ff is a directory // // The following is a heuristic to figure out if the base refers to a file or dir. It's not perfect, because // the resource referred to by this path may not actually exist, but it's the best I can do boolean baseIsFile = true; File baseResource = new File(normalizedBasePath); if (baseResource.exists()) { baseIsFile = baseResource.isFile(); } else if (basePath.endsWith(pathSeparator)) { baseIsFile = false; } StringBuilder relative = new StringBuilder(); if (base.length != commonIndex) { int numDirsUp = baseIsFile ? base.length - commonIndex - 1 : base.length - commonIndex; for (int i = 0; i < numDirsUp; i++) { relative.append(".." + pathSeparator); } } relative.append(normalizedTargetPath.substring(common.length())); return relative.toString(); } static class PathResolutionException extends RuntimeException { private static final long serialVersionUID = -6747166042664389937L; PathResolutionException(String msg) { super(msg); } } public static boolean isSymbolicLink(File file) throws IOException { if (file == null || !file.exists()) return false; PrintStream printStream = new PrintStream(new ByteArrayOutputStream(), true, Charset.defaultCharset().name()); try { int result = Forker.forkProcess(printStream, file.getParentFile(), "test", "-L", file.getName()); return result == 0; } finally { IOUtils.closeQuietly(printStream); } } public static void createSymbolicLink(final File source, final File target) throws IOException { System.out.println("[INFO] Creating symbolic link. Source:" + source.getAbsolutePath() + ", target: " + target.getAbsolutePath() + "."); mkdirs(target.getParentFile()); int returnValue = Forker.forkProcess(System.out, null, "ln", "-sf", source.getAbsolutePath(), target.getAbsolutePath()); if (returnValue != 0) { throw new RuntimeException("Cannot create symbolic link from '" + source + "' to '" + target + "'. Return value:" + returnValue); } } public static boolean isChild(File parent, File child) { return isChild(split(parent.getAbsoluteFile()), split(child.getAbsoluteFile())); } private static boolean isChild(List<String> parent, List<String> child) { if (child.size() < parent.size()) return false; for (int index = 0, size = parent.size(); index < size; index++) if (!parent.get(index).equals(child.get(index))) return false; return true; } public static String ensureLeadingSlash(final String path) { return path.startsWith("/") ? path : "/" + path; } public static String getAppendix(final File f) { final String fileName = f.getName(); int indexOfLastDot = fileName.lastIndexOf(DOT); if (indexOfLastDot < 0) { return null; } return fileName.substring(indexOfLastDot + DOT.length()); } static void unarchive(final ArchiverManager archiverManager, final String archiverId, final File source, final File destinationDirectory) { try { UnArchiver unarchiver = archiverManager.getUnArchiver(archiverId); unarchiver.setSourceFile(source); unarchiver.setDestDirectory(destinationDirectory); unarchiver.extract(); } catch (NoSuchArchiverException e) { throw new RuntimeException(e); } catch (ArchiverException e) { throw new RuntimeException(e); } } static String getCanonicalPath(File f) throws IORuntimeException { try { return f.getCanonicalPath(); } catch (final IOException ex) { throw new IORuntimeException(ex.getMessage(), ex); } } static File getCanonicalFile(File f) throws IORuntimeException { try { return f.getCanonicalFile(); } catch (final IOException ex) { throw new IORuntimeException(ex.getMessage(), ex); } } public static class IORuntimeException extends RuntimeException { /** * */ private static final long serialVersionUID = -833352788241793404L; public IORuntimeException(String message, Throwable cause) { super(message, cause); } } }