/* * Copyright 2010 Google Inc. * * 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 com.google.doctool.custom; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintStream; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.regex.Pattern; /** * Used by trunk/doc/build.xml to generate the packages.properties file. */ public class FindPackages { /** * A list of regular expressions to exclude. For readability, a '.' character * will be interpreted literally (i.e., it will be transformed into '\.' * before being compiled). Add rules here as needed. */ private static final String[] EXCLUSIONS = { "^com.example.", "^com.google.gwt.dev(.|$)", "^com.google.gwt.emul.", "^com.google.gwt.examples(.|$)", "^com.google.gwt.i18n.server(.|$)", "^com.google.gwt.i18n.tools", "^com.google.gwt.lang", "^com.google.gwt.junit(.|$)", "^com.google.gwt.resources.css(.|$)", "^com.google.gwt.resources.rg(.|$)", "^com.google.gwt.rpc.client.ast(.|$)", "^com.google.gwt.soyc(.|$)", "^com.google.gwt.validation(.|$)", "^com.google.gwt.user.\\w+.rpc.core.", "^javax.", "^junit.", "^org.", ".impl(.|$)", ".rebind(.|$)" }; /** * A list of emulated packages in the java.* namespace, to be emitted as * the JAVA_PKGS property. Add packages here as needed. */ private static final String[] JAVA_PKGS = { "java.lang", "java.lang.annotation", "java.math", "java.io", "java.sql", "java.util", "java.util.logging"}; /** * User packages to include, regardless of exclusions. Add packages here * as needed. */ private static final String[] PACKAGE_WHITELIST = { "com.google.gwt.i18n.rebind.format", "com.google.gwt.i18n.rebind.keygen", "com.google.gwt.junit.client"}; /** * Source directories under the root directory to traverse. Add directories * here as needed. */ private static final String[] SOURCE_DIRS = { "user/src", "user/javadoc", "user/super", "dev/core/src", "dev/core/super"}; /** * Individual user classes to include, even if the rest of their packages * is not included. Add classes here as needed. */ private static final String[] USER_CLASSES = { "user/src/com/google/gwt/junit/tools/GWTTestSuite.java", "user/src/com/google/gwt/i18n/rebind/LocaleUtils.java", "user/src/com/google/gwt/i18n/server/GwtLocaleFactoryImpl.java", "user/src/com/google/gwt/i18n/server/GwtLocaleImpl.java"}; private static Pattern exclusions; static { StringBuilder sb = new StringBuilder(); for (int i = 0; i < EXCLUSIONS.length; i++) { String ex = EXCLUSIONS[i]; ex = ex.replace(".", "\\."); if (i < EXCLUSIONS.length - 1) { sb.append(ex + "|"); } else { sb.append(ex); } } exclusions = Pattern.compile(sb.toString()); } public static void main(String[] args) { if (args.length < 1) { System.err.println("usage: java com.google.doctool.custom.FindPackages <root dir>"); System.exit(1); } try { File rootDir = new File(args[0]); // Output to <root>/doc/packages.properties File build = new File(rootDir, "build"); File buildOut = new File(build, "out"); File outFile = new File(buildOut, "packages.properties"); PrintStream out = new PrintStream(new FileOutputStream(outFile), false, "UTF-8"); out.println("# THIS FILE IS AUTOMATICALLY GENERATED BY"); out.println("# com.google.doctool.custom.FindPackages"); out.println("#"); out.println("# This file contains all of the user javadoc packages"); out.println("#"); out.println("# JRE emulation packages"); out.println("JAVA_PKGS=\\"); for (int i = 0; i < JAVA_PKGS.length; i++) { if (i < JAVA_PKGS.length - 1) { out.println(JAVA_PKGS[i] + ";\\"); } else { out.println(JAVA_PKGS[i]); } } out.println("# The last package should not have a trailing semicolon"); out.println(""); out.println("# Individual classes to include when we don't want to include an entire package"); out.println("USER_CLASSES=\\"); // Output a package-info.java once for each package Set<String> classPaths = new HashSet<String>(); for (int i = 0; i < USER_CLASSES.length; i++) { String className = USER_CLASSES[i]; String classPath = className.substring(0, className.lastIndexOf('/')); if (!classPaths.contains(classPath)) { classPaths.add(classPath); out.println("${gwt.root}/" + classPath + "/package-info.java" + ":\\"); } if (i < USER_CLASSES.length - 1) { out.println("${gwt.root}/" + className + ":\\"); } else { out.println("${gwt.root}/" + className); } } out.println(""); out.println("# Packages to include"); out.println("USER_PKGS=\\"); Set<String> packages = new HashSet<String>(); for (String dir : SOURCE_DIRS) { File f = new File(rootDir, dir); findPackages(f, null, packages); } for (String s : PACKAGE_WHITELIST) { packages.add(s); } ArrayList<String> packageList = new ArrayList<String>(packages); Collections.sort(packageList); for (int i = 0; i < packages.size(); i++) { if (i < packages.size() - 1) { out.println(packageList.get(i) + ";\\"); } else { out.println(packageList.get(i)); } } out.println("# The last package should not have a trailing semicolon"); out.close(); } catch (IOException e) { System.err.println("Got I/O Exception: " + e); System.exit(2); } } /** * Recursively find java packages under the given directory. * * @param dir the root directory * @param packageName the package name so far * @param packages the set of packages to output to */ private static void findPackages(File dir, String packageName, Set<String> packages) { File[] files = dir.listFiles(); if (files == null) { return; } boolean hasJava = false; for (File f : files) { String name = f.getName(); if (f.isDirectory()) { String subPackage = packageName == null ? name : packageName + "." + name; findPackages(f, subPackage, packages); } else { // If there is a java file in the directory, include the package // for further processing. if (!hasJava && name.endsWith(".java")) { hasJava = true; } } } // Clean up translatable/ and super/ paths // Emit the package name if not excluded if (hasJava && packageName != null) { int index; if ((index = packageName.indexOf(".translatable.")) != -1) { packageName = packageName.substring(index + 14); } if ((index = packageName.indexOf(".super.")) != -1) { packageName = packageName.substring(index + 7); } if (!exclusions.matcher(packageName).find()) { packages.add(packageName); } } } }