| /* |
| * 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.beans", |
| "java.io", |
| "java.lang", "java.lang.annotation", "java.lang.reflect", |
| "java.math", |
| "java.nio.charset", |
| "java.security", |
| "java.sql", |
| "java.text", |
| "java.util", "java.util.concurrent", "java.util.concurrent.atomic", "java.util.function", "java.util.logging", "java.util.stream" |
| }; |
| |
| /** |
| * 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); |
| } |
| } |
| } |
| } |