1.9.30 sync.
[gae.git] / java / src / main / com / google / appengine / tools / enhancer / Enhance.java
blob1d294d76ebac2288e6b9ad5c0a45a46e86530f84
1 // Copyright 2008 Google Inc. All rights reserved.
3 package com.google.appengine.tools.enhancer;
5 import com.google.appengine.tools.info.SdkImplInfo;
6 import com.google.appengine.tools.util.Logging;
8 import java.io.File;
9 import java.io.FileWriter;
10 import java.io.IOException;
11 import java.io.PrintWriter;
12 import java.net.URL;
13 import java.net.URLClassLoader;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.HashSet;
17 import java.util.List;
18 import java.util.Set;
20 /**
21 * The command-line interface for ORM enhancing. Usage:
22 * <pre>
23 * java -cp [classpath]
24 * com.google.appengine.tools.enhancer.Enhance [options] [jdo-files] [class-files]
25 * where options can be
26 * -persistenceUnit [persistence-unit-name] : Name of a "persistence-unit" containing the classes
27 * to enhance
28 * -d [target-dir-name] : Write the enhanced classes to the specified directory
29 * -api [api-name] : Name of the API we are enhancing for (JDO, JPA). Default is JDO
30 * -enhancerName [name] : Name of the ClassEnhancer to use. Options ASM
31 * -checkonly : Just check the classes for enhancement status
32 * -v : verbose output
33 * -enhancerVersion [version] : The version of the DataNucleus enhancer to use, where version
34 * corresponds to a directory under lib/opt/user/datanucleus in the
35 * sdk.
37 * where classpath must contain the following
38 * - your classes
39 * - your meta-data files
40 * <pre>
43 public class Enhance {
45 static final String DATANUCLEUS_VERSION_ARG = "-enhancerVersion";
47 public static void main(String[] args) {
48 Logging.initializeLogging();
49 new Enhance(args);
52 public Enhance(String[] args) {
53 PrintWriter writer;
54 File logFile;
56 try {
57 logFile = File.createTempFile("enhance", ".log");
58 writer = new PrintWriter(new FileWriter(logFile), true);
59 } catch (IOException e) {
60 throw new RuntimeException("Unable to enable logging.", e);
63 try {
64 Set<URL> targets = getEnhanceTargets();
65 Enhancer enhancer = new Enhancer();
66 enhancer.setTargets(targets);
67 args = processArgs(enhancer, args);
68 enhancer.setArgs(args);
69 enhancer.execute();
70 } catch (Exception e) {
71 System.out.println("Encountered a problem: " + e.getMessage());
72 System.out.println("Please see the logs [" + logFile.getAbsolutePath() +
73 "] for further information.");
74 e.printStackTrace(writer);
75 System.exit(1);
79 /**
80 * Some of the {@code args} are destined for us (App Engine) and some of the
81 * args are destined for DataNucleus. This method processes the args that
82 * are for us and returns a version of the provided array with the processed
83 * args removed.
85 static String[] processArgs(Enhancer enhancer, String[] args) {
86 List<String> processed = new ArrayList<String>();
87 for (int i = 0; i < args.length; i++) {
88 if (!args[i].startsWith("-") || !args[i].equals(DATANUCLEUS_VERSION_ARG)) {
89 processed.add(args[i]);
90 continue;
92 if (++i == args.length) {
93 throw new IllegalArgumentException(
94 String.format("Missing value for option %s", DATANUCLEUS_VERSION_ARG));
96 enhancer.setDatanucleusVersion(args[i]);
98 return processed.toArray(new String[processed.size()]);
102 * We assume that every URL on our classpath is an enhancer target.
103 * This is ugly, but it's how DataNucleus does it and is currently
104 * the path of least resistance.
106 private Set<URL> getEnhanceTargets() {
107 URLClassLoader myLoader = (URLClassLoader) getClass().getClassLoader();
108 URL[] urls = myLoader.getURLs();
109 Set<URL> enhanceTargets = new HashSet<URL>(Arrays.asList(urls));
110 URL toolsJar = SdkImplInfo.getToolsApiJar();
111 for (URL url : enhanceTargets) {
112 if (url.sameFile(toolsJar)) {
113 enhanceTargets.remove(toolsJar);
114 break;
118 return enhanceTargets;