1 package org.codehaus.mojo.rmic;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import org.apache.maven.plugin.logging.Log;
26 import org.codehaus.plexus.compiler.CompilerException;
27 import org.codehaus.plexus.util.StringUtils;
28
29 import java.io.File;
30 import java.io.OutputStream;
31 import java.lang.reflect.Constructor;
32 import java.lang.reflect.InvocationTargetException;
33 import java.lang.reflect.Method;
34 import java.net.URL;
35 import java.net.URLClassLoader;
36 import java.util.ArrayList;
37 import java.util.List;
38
39
40
41
42 abstract class AbstractRmiCompiler implements RmiCompiler
43 {
44 private Log logger;
45
46
47 private static ClassLoaderFacade classLoaderFacade = new ClassLoaderFacadeImpl();
48
49 public void setLog( Log log )
50 {
51 logger = log;
52 }
53
54 public Log getLog()
55 {
56 return logger;
57 }
58
59
60
61
62
63 static ClassLoaderFacade getClassLoaderFacade()
64 {
65 return classLoaderFacade;
66 }
67
68
69
70
71
72
73
74 public void execute( RmiCompilerConfiguration rmiConfig )
75 throws RmiCompilerException
76 {
77
78
79
80
81 List<String> arguments = new ArrayList<>();
82
83 List<String> classpathList = rmiConfig.getClasspathEntries();
84 if ( classpathList.size() > 0 )
85 {
86 arguments.add( "-classpath" );
87 arguments.add( buildClasspath( classpathList ) );
88 }
89
90 arguments.add( "-d" );
91 arguments.add( rmiConfig.getOutputLocation() );
92
93 if ( rmiConfig.getVersion() != null )
94 {
95 arguments.add( "-v" + rmiConfig.getVersion() );
96 }
97
98 if ( rmiConfig.isIiop() )
99 {
100 arguments.add( "-iiop" );
101
102 if ( rmiConfig.isPoa() )
103 {
104 arguments.add( "-poa" );
105 }
106 if ( rmiConfig.isNoLocalStubs() )
107 {
108 arguments.add( "-nolocalstubs" );
109 }
110 }
111 else
112 {
113 if ( rmiConfig.isPoa() )
114 {
115 throw new RmiCompilerException( "IIOP must be enabled in order to use the POA option" );
116 }
117
118 }
119
120 if ( rmiConfig.isIdl() )
121 {
122 arguments.add( "-idl" );
123 if ( rmiConfig.isNoValueMethods() )
124 {
125 arguments.add( "-noValueMethods" );
126 }
127 }
128
129 if ( rmiConfig.isKeep() )
130 {
131 arguments.add( "-keep" );
132 }
133
134 if ( getLog().isDebugEnabled() || rmiConfig.isVerbose() )
135 {
136 arguments.add( "-verbose" );
137 }
138 else if ( rmiConfig.isNowarn() )
139 {
140 arguments.add( "-nowarn" );
141 }
142
143 for ( File remoteClass : rmiConfig.getSourceFiles() )
144 {
145 arguments.add( fileToClassName( remoteClass.getPath() ) );
146 }
147
148 String[] args = arguments.toArray( new String[arguments.size()] );
149
150 if ( getLog().isDebugEnabled() )
151 {
152 getLog().debug( "rmic arguments: " );
153
154 for ( String arg : args )
155 {
156 getLog().debug( arg );
157 }
158 }
159
160 try
161 {
162 compileInProcess( args );
163 }
164 catch ( CompilerException e )
165 {
166 throw new RmiCompilerException( e.getMessage(), e );
167 }
168 }
169
170 private String buildClasspath( List<String> classpathList )
171 {
172 StringBuilder classpath = new StringBuilder( classpathList.get( 0 ) );
173 for ( int i = 1; i < classpathList.size(); i++ )
174 {
175 classpath.append( File.pathSeparator ).append( classpathList.get( i ) );
176 }
177
178 return classpath.toString();
179 }
180
181 private static String fileToClassName( String classFileName )
182 {
183 return StringUtils.replace( StringUtils.replace( classFileName, ".class", "" ), File.separator, "." );
184 }
185
186 protected void compileInProcess( String[] args )
187 throws CompilerException
188 {
189 final Class<?> mainClass = createMainClass();
190 final Thread thread = Thread.currentThread();
191 final ClassLoader contextClassLoader = thread.getContextClassLoader();
192 thread.setContextClassLoader( mainClass.getClassLoader() );
193 try
194 {
195 compileInProcess0( mainClass, args );
196 }
197 finally
198 {
199 thread.setContextClassLoader( contextClassLoader );
200 }
201 }
202
203 protected abstract Class<?> createMainClass()
204 throws CompilerException;
205
206 private static void compileInProcess0( Class<?> rmicMainClass, String[] args )
207 throws CompilerException
208 {
209 try
210 {
211 Constructor<?> constructor = rmicMainClass.getConstructor( OutputStream.class, String.class );
212
213 Object main = constructor.newInstance( System.out, "rmic" );
214
215 Method compile = rmicMainClass.getMethod( "compile", String[].class );
216
217 compile.invoke( main, new Object[] { args } );
218 }
219 catch ( NoSuchMethodException | IllegalAccessException | IllegalArgumentException
220 | InstantiationException | InvocationTargetException e )
221 {
222 throw new CompilerException( "Error while executing the compiler.", e );
223 }
224 }
225
226
227
228
229 interface ClassLoaderFacade
230 {
231
232
233
234
235
236 void prependUrls( URL... urls );
237
238
239
240
241
242
243
244
245 Class<?> loadClass( String rmiCompilerClass ) throws ClassNotFoundException;
246 }
247
248
249
250
251 private static class ClassLoaderFacadeImpl implements ClassLoaderFacade
252 {
253 ClassLoader classLoader = getClass().getClassLoader();
254
255 public void prependUrls( URL... urls )
256 {
257 classLoader = new URLClassLoader( urls, classLoader );
258 }
259
260 public Class<?> loadClass( String rmiCompilerClass ) throws ClassNotFoundException
261 {
262 return classLoader.loadClass( rmiCompilerClass );
263 }
264
265 }
266 }