blob: 7a3459c2164247d60f2773c2961c8cd0c2c37075 [file] [log] [blame]
/*
* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.apple.internal.jobjc.generator;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Pattern;
import com.apple.internal.jobjc.generator.model.Framework;
import com.apple.internal.jobjc.generator.model.Framework.FrameworkDependency;
import com.apple.internal.jobjc.generator.utils.Fp;
public class Utils {
public static boolean isLeopard = System.getProperty("os.version").startsWith("10.5");
public static boolean isSnowLeopard = System.getProperty("os.version").startsWith("10.6");
@SuppressWarnings("unchecked")
public static <T> List<T> list(final Object...args) {
final ArrayList<Object> list = new ArrayList<Object>(args.length);
for (final Object arg : args) list.add(arg);
return (List<T>)list;
}
/**
* A small implementation of UNIX find.
* @param matchRegex Only collect paths that match this regex.
* @param pruneRegex Don't recurse down a path that matches this regex. May be null.
* @throws IOException if File.getCanonicalPath() fails.
*/
public static List<File> find(final File startpath, final String matchRegex, final String pruneRegex) throws IOException{
final Pattern matchPattern = Pattern.compile(matchRegex, Pattern.CASE_INSENSITIVE);
final Pattern prunePattern = pruneRegex == null ? null : Pattern.compile(pruneRegex, Pattern.CASE_INSENSITIVE);
final Set<String> visited = new HashSet<String>();
final List<File> found = new ArrayList<File>();
class Search{
void search(final File path) throws IOException{
if(prunePattern != null && prunePattern.matcher(path.getAbsolutePath()).matches()) return;
String cpath = path.getCanonicalPath();
if(!visited.add(cpath)) return;
if(matchPattern.matcher(path.getAbsolutePath()).matches())
found.add(path);
if(path.isDirectory())
for(File sub : path.listFiles())
search(sub);
}
}
new Search().search(startpath);
return found;
}
public static String joinWComma(final List<?> list) { return Fp.join(", ", list); }
public static String joinWComma(final Object[] list) { return Fp.join(", ", Arrays.asList(list)); }
public static class Substituter {
String str;
public Substituter(final String str) {
this.str = str.replaceAll("\\#", "\t").replaceAll("\\~", "\n");
}
public void replace(final String key, final String value) {
str = str.replaceAll("\\$" + key, value);
}
/**
* Apply String.format first, and then pass through Substituter.
*/
public static String format(String format, Object... args){
return new Substituter(String.format(format, args)).toString();
}
@Override public String toString() {
return str;
}
}
static Map<String, String> getArgs(final String...args) {
final Map<String, String> argMap = new HashMap<String, String>();
for (final String arg : args) {
final String[] splitArg = arg.split("\\=");
if (splitArg.length != 2) continue;
argMap.put(splitArg[0], splitArg[1]);
}
return argMap;
}
static void recDelete(final File file) {
if (!file.exists()) return;
if (file.isDirectory()) for (final File f : file.listFiles()) recDelete(f);
file.delete();
}
public static String capitalize(String s){
if(s.length() == 0) return s;
return Character.toString(Character.toUpperCase(s.charAt(0))) + s.substring(1);
}
/**
* Sort frameworks by dependencies. If A is a dependency of B,
* then A will come before B in the list.
*/
public static void topologicalSort(final List<Framework> frameworks) {
final Set<Framework> visited = new TreeSet<Framework>();
final List<Framework> sorted = new ArrayList<Framework>(frameworks.size());
class Rec{
void visit(final Framework fw){
if(!visited.add(fw)) return;
for(FrameworkDependency dep : fw.dependencies)
if(dep.object != null)
visit(dep.object);
sorted.add(fw);
}
}
for(Framework fw : frameworks) new Rec().visit(fw);
frameworks.clear();
frameworks.addAll(sorted);
}
/**
* If there is a cycle it is returned. Otherwise null is returned.
*/
public static List<Framework> getDependencyCycle(List<Framework> frameworks) {
@SuppressWarnings("serial")
class FoundCycle extends Throwable{
public final List<Framework> cycle;
public FoundCycle(List<Framework> cycle){
this.cycle = cycle;
}
};
class Rec{
void visit(final Framework fw, List<Framework> visited) throws FoundCycle{
visited = new LinkedList<Framework>(visited);
if(visited.contains(fw)){
visited.add(fw);
throw new FoundCycle(visited);
}
visited.add(fw);
for(FrameworkDependency dep : fw.dependencies)
if(dep.object != null)
visit(dep.object, visited);
}
}
try{ for(Framework fw : frameworks){ new Rec().visit(fw, new LinkedList<Framework>()); }}
catch(FoundCycle x){ return x.cycle; }
return null;
}
public static String getCanonicalPath(File file) throws RuntimeException{
try {
return file.getCanonicalPath();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}