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
;
9 import java
.io
.FileWriter
;
10 import java
.io
.IOException
;
11 import java
.io
.PrintWriter
;
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
;
21 * The command-line interface for ORM enhancing. Usage:
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
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
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
37 * where classpath must contain the following
39 * - your meta-data files
43 public class Enhance
{
45 static final String DATANUCLEUS_VERSION_ARG
= "-enhancerVersion";
47 public static void main(String
[] args
) {
48 Logging
.initializeLogging();
52 public Enhance(String
[] args
) {
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
);
64 Set
<URL
> targets
= getEnhanceTargets();
65 Enhancer enhancer
= new Enhancer();
66 enhancer
.setTargets(targets
);
67 args
= processArgs(enhancer
, args
);
68 enhancer
.setArgs(args
);
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
);
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
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
]);
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
);
118 return enhanceTargets
;