1 | /*
|
---|
2 | * Copyright 2001-2004 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 |
|
---|
18 | package org.apache.tools.ant.taskdefs.rmic;
|
---|
19 |
|
---|
20 | import java.io.File;
|
---|
21 | import java.util.Random;
|
---|
22 | import java.util.Vector;
|
---|
23 | import org.apache.tools.ant.Project;
|
---|
24 | import org.apache.tools.ant.taskdefs.Rmic;
|
---|
25 | import org.apache.tools.ant.types.Commandline;
|
---|
26 | import org.apache.tools.ant.types.Path;
|
---|
27 | import org.apache.tools.ant.util.FileNameMapper;
|
---|
28 | import org.apache.tools.ant.util.JavaEnvUtils;
|
---|
29 |
|
---|
30 | /**
|
---|
31 | * This is the default implementation for the RmicAdapter interface.
|
---|
32 | * Currently, this is a cut-and-paste of the original rmic task and
|
---|
33 | * DefaultCopmpilerAdapter.
|
---|
34 | *
|
---|
35 | * @since Ant 1.4
|
---|
36 | */
|
---|
37 | public abstract class DefaultRmicAdapter implements RmicAdapter {
|
---|
38 |
|
---|
39 | private Rmic attributes;
|
---|
40 | private FileNameMapper mapper;
|
---|
41 | private static final Random rand = new Random();
|
---|
42 |
|
---|
43 | public DefaultRmicAdapter() {
|
---|
44 | }
|
---|
45 |
|
---|
46 | public void setRmic(Rmic attributes) {
|
---|
47 | this.attributes = attributes;
|
---|
48 | mapper = new RmicFileNameMapper();
|
---|
49 | }
|
---|
50 |
|
---|
51 | public Rmic getRmic() {
|
---|
52 | return attributes;
|
---|
53 | }
|
---|
54 |
|
---|
55 | protected String getStubClassSuffix() {
|
---|
56 | return "_Stub";
|
---|
57 | }
|
---|
58 |
|
---|
59 | protected String getSkelClassSuffix() {
|
---|
60 | return "_Skel";
|
---|
61 | }
|
---|
62 |
|
---|
63 | protected String getTieClassSuffix() {
|
---|
64 | return "_Tie";
|
---|
65 | }
|
---|
66 |
|
---|
67 | /**
|
---|
68 | * This implementation returns a mapper that may return up to two
|
---|
69 | * file names.
|
---|
70 | *
|
---|
71 | * <ul>
|
---|
72 | * <li>for JRMP it will return *_getStubClassSuffix (and
|
---|
73 | * *_getSkelClassSuffix if JDK 1.1 is used)</li>
|
---|
74 | *
|
---|
75 | * <li>for IDL it will return a random name, causing <rmic> to
|
---|
76 | * always recompile.</li>
|
---|
77 | *
|
---|
78 | * <li>for IIOP it will return _*_getStubClassSuffix for
|
---|
79 | * interfaces and _*_getStubClassSuffix for non-interfaces (and
|
---|
80 | * determine the interface and create _*_Stub from that).</li>
|
---|
81 | * </ul>
|
---|
82 | */
|
---|
83 | public FileNameMapper getMapper() {
|
---|
84 | return mapper;
|
---|
85 | }
|
---|
86 |
|
---|
87 | /**
|
---|
88 | * The CLASSPATH this rmic process will use.
|
---|
89 | */
|
---|
90 | public Path getClasspath() {
|
---|
91 | return getCompileClasspath();
|
---|
92 | }
|
---|
93 |
|
---|
94 | /**
|
---|
95 | * Builds the compilation classpath.
|
---|
96 | */
|
---|
97 | protected Path getCompileClasspath() {
|
---|
98 | Path classpath = new Path(attributes.getProject());
|
---|
99 | // add dest dir to classpath so that previously compiled and
|
---|
100 | // untouched classes are on classpath
|
---|
101 | classpath.setLocation(attributes.getBase());
|
---|
102 |
|
---|
103 | // Combine the build classpath with the system classpath, in an
|
---|
104 | // order determined by the value of build.sysclasspath
|
---|
105 |
|
---|
106 | Path cp = attributes.getClasspath();
|
---|
107 | if (cp == null) {
|
---|
108 | cp = new Path(attributes.getProject());
|
---|
109 | }
|
---|
110 | if (attributes.getIncludeantruntime()) {
|
---|
111 | classpath.addExisting(cp.concatSystemClasspath("last"));
|
---|
112 | } else {
|
---|
113 | classpath.addExisting(cp.concatSystemClasspath("ignore"));
|
---|
114 | }
|
---|
115 |
|
---|
116 | if (attributes.getIncludejavaruntime()) {
|
---|
117 | classpath.addJavaRuntime();
|
---|
118 | }
|
---|
119 | return classpath;
|
---|
120 | }
|
---|
121 |
|
---|
122 | /**
|
---|
123 | * setup rmic argument for rmic.
|
---|
124 | */
|
---|
125 | protected Commandline setupRmicCommand() {
|
---|
126 | return setupRmicCommand(null);
|
---|
127 | }
|
---|
128 |
|
---|
129 | /**
|
---|
130 | * setup rmic argument for rmic.
|
---|
131 | *
|
---|
132 | * @param options additional parameters needed by a specific
|
---|
133 | * implementation.
|
---|
134 | */
|
---|
135 | protected Commandline setupRmicCommand(String[] options) {
|
---|
136 | Commandline cmd = new Commandline();
|
---|
137 |
|
---|
138 | if (options != null) {
|
---|
139 | for (int i = 0; i < options.length; i++) {
|
---|
140 | cmd.createArgument().setValue(options[i]);
|
---|
141 | }
|
---|
142 | }
|
---|
143 |
|
---|
144 | Path classpath = getCompileClasspath();
|
---|
145 |
|
---|
146 | cmd.createArgument().setValue("-d");
|
---|
147 | cmd.createArgument().setFile(attributes.getBase());
|
---|
148 |
|
---|
149 | if (attributes.getExtdirs() != null) {
|
---|
150 | if (JavaEnvUtils.isJavaVersion(JavaEnvUtils.JAVA_1_1)) {
|
---|
151 | /*
|
---|
152 | * XXX - This doesn't mix very well with build.systemclasspath,
|
---|
153 | */
|
---|
154 | classpath.addExtdirs(attributes.getExtdirs());
|
---|
155 | } else {
|
---|
156 | cmd.createArgument().setValue("-extdirs");
|
---|
157 | cmd.createArgument().setPath(attributes.getExtdirs());
|
---|
158 | }
|
---|
159 | }
|
---|
160 |
|
---|
161 | cmd.createArgument().setValue("-classpath");
|
---|
162 | cmd.createArgument().setPath(classpath);
|
---|
163 |
|
---|
164 | String stubVersion = attributes.getStubVersion();
|
---|
165 | if (null != stubVersion) {
|
---|
166 | if ("1.1".equals(stubVersion)) {
|
---|
167 | cmd.createArgument().setValue("-v1.1");
|
---|
168 | } else if ("1.2".equals(stubVersion)) {
|
---|
169 | cmd.createArgument().setValue("-v1.2");
|
---|
170 | } else {
|
---|
171 | cmd.createArgument().setValue("-vcompat");
|
---|
172 | }
|
---|
173 | }
|
---|
174 |
|
---|
175 | if (null != attributes.getSourceBase()) {
|
---|
176 | cmd.createArgument().setValue("-keepgenerated");
|
---|
177 | }
|
---|
178 |
|
---|
179 | if (attributes.getIiop()) {
|
---|
180 | attributes.log("IIOP has been turned on.", Project.MSG_INFO);
|
---|
181 | cmd.createArgument().setValue("-iiop");
|
---|
182 | if (attributes.getIiopopts() != null) {
|
---|
183 | attributes.log("IIOP Options: " + attributes.getIiopopts(),
|
---|
184 | Project.MSG_INFO);
|
---|
185 | cmd.createArgument().setValue(attributes.getIiopopts());
|
---|
186 | }
|
---|
187 | }
|
---|
188 |
|
---|
189 | if (attributes.getIdl()) {
|
---|
190 | cmd.createArgument().setValue("-idl");
|
---|
191 | attributes.log("IDL has been turned on.", Project.MSG_INFO);
|
---|
192 | if (attributes.getIdlopts() != null) {
|
---|
193 | cmd.createArgument().setValue(attributes.getIdlopts());
|
---|
194 | attributes.log("IDL Options: " + attributes.getIdlopts(),
|
---|
195 | Project.MSG_INFO);
|
---|
196 | }
|
---|
197 | }
|
---|
198 |
|
---|
199 | if (attributes.getDebug()) {
|
---|
200 | cmd.createArgument().setValue("-g");
|
---|
201 | }
|
---|
202 |
|
---|
203 | cmd.addArguments(attributes.getCurrentCompilerArgs());
|
---|
204 |
|
---|
205 | logAndAddFilesToCompile(cmd);
|
---|
206 | return cmd;
|
---|
207 | }
|
---|
208 |
|
---|
209 | /**
|
---|
210 | * Logs the compilation parameters, adds the files to compile and logs the
|
---|
211 | * &qout;niceSourceList"
|
---|
212 | */
|
---|
213 | protected void logAndAddFilesToCompile(Commandline cmd) {
|
---|
214 | Vector compileList = attributes.getCompileList();
|
---|
215 |
|
---|
216 | attributes.log("Compilation " + cmd.describeArguments(),
|
---|
217 | Project.MSG_VERBOSE);
|
---|
218 |
|
---|
219 | StringBuffer niceSourceList = new StringBuffer("File");
|
---|
220 | if (compileList.size() != 1) {
|
---|
221 | niceSourceList.append("s");
|
---|
222 | }
|
---|
223 | niceSourceList.append(" to be compiled:");
|
---|
224 |
|
---|
225 | for (int i = 0; i < compileList.size(); i++) {
|
---|
226 | String arg = (String) compileList.elementAt(i);
|
---|
227 | cmd.createArgument().setValue(arg);
|
---|
228 | niceSourceList.append(" " + arg);
|
---|
229 | }
|
---|
230 |
|
---|
231 | attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE);
|
---|
232 | }
|
---|
233 |
|
---|
234 | /**
|
---|
235 | * Mapper that may return up to two file names.
|
---|
236 | *
|
---|
237 | * <ul>
|
---|
238 | * <li>for JRMP it will return *_getStubClassSuffix (and
|
---|
239 | * *_getSkelClassSuffix if JDK 1.1 is used)</li>
|
---|
240 | *
|
---|
241 | * <li>for IDL it will return a random name, causing <rmic> to
|
---|
242 | * always recompile.</li>
|
---|
243 | *
|
---|
244 | * <li>for IIOP it will return _*_getStubClassSuffix for
|
---|
245 | * interfaces and _*_getStubClassSuffix for non-interfaces (and
|
---|
246 | * determine the interface and create _*_Stub from that).</li>
|
---|
247 | * </ul>
|
---|
248 | */
|
---|
249 | private class RmicFileNameMapper implements FileNameMapper {
|
---|
250 |
|
---|
251 | RmicFileNameMapper() {
|
---|
252 | }
|
---|
253 |
|
---|
254 | /**
|
---|
255 | * Empty implementation.
|
---|
256 | */
|
---|
257 | public void setFrom(String s) {
|
---|
258 | }
|
---|
259 | /**
|
---|
260 | * Empty implementation.
|
---|
261 | */
|
---|
262 | public void setTo(String s) {
|
---|
263 | }
|
---|
264 |
|
---|
265 | public String[] mapFileName(String name) {
|
---|
266 | if (name == null
|
---|
267 | || !name.endsWith(".class")
|
---|
268 | || name.endsWith(getStubClassSuffix() + ".class")
|
---|
269 | || name.endsWith(getSkelClassSuffix() + ".class")
|
---|
270 | || name.endsWith(getTieClassSuffix() + ".class")) {
|
---|
271 | // Not a .class file or the one we'd generate
|
---|
272 | return null;
|
---|
273 | }
|
---|
274 |
|
---|
275 | // we know that name.endsWith(".class")
|
---|
276 | String base = name.substring(0, name.length() - 6);
|
---|
277 |
|
---|
278 | String classname = base.replace(File.separatorChar, '.');
|
---|
279 | if (attributes.getVerify()
|
---|
280 | && !attributes.isValidRmiRemote(classname)) {
|
---|
281 | return null;
|
---|
282 | }
|
---|
283 |
|
---|
284 | /*
|
---|
285 | * fallback in case we have trouble loading the class or
|
---|
286 | * don't know how to handle it (there is no easy way to
|
---|
287 | * know what IDL mode would generate.
|
---|
288 | *
|
---|
289 | * This is supposed to make Ant always recompile the
|
---|
290 | * class, as a file of that name should not exist.
|
---|
291 | */
|
---|
292 | String[] target = new String[] {name + ".tmp." + rand.nextLong()};
|
---|
293 |
|
---|
294 | if (!attributes.getIiop() && !attributes.getIdl()) {
|
---|
295 | // JRMP with simple naming convention
|
---|
296 | if ("1.2".equals(attributes.getStubVersion())) {
|
---|
297 | target = new String[] {
|
---|
298 | base + getStubClassSuffix() + ".class"
|
---|
299 | };
|
---|
300 | } else {
|
---|
301 | target = new String[] {
|
---|
302 | base + getStubClassSuffix() + ".class",
|
---|
303 | base + getSkelClassSuffix() + ".class",
|
---|
304 | };
|
---|
305 | }
|
---|
306 | } else if (!attributes.getIdl()) {
|
---|
307 | int lastSlash = base.lastIndexOf(File.separatorChar);
|
---|
308 |
|
---|
309 | String dirname = "";
|
---|
310 | /*
|
---|
311 | * I know, this is not necessary, but I prefer it explicit (SB)
|
---|
312 | */
|
---|
313 | int index = -1;
|
---|
314 | if (lastSlash == -1) {
|
---|
315 | // no package
|
---|
316 | index = 0;
|
---|
317 | } else {
|
---|
318 | index = lastSlash + 1;
|
---|
319 | dirname = base.substring(0, index);
|
---|
320 | }
|
---|
321 |
|
---|
322 | String filename = base.substring(index);
|
---|
323 |
|
---|
324 | try {
|
---|
325 | Class c = attributes.getLoader().loadClass(classname);
|
---|
326 |
|
---|
327 | if (c.isInterface()) {
|
---|
328 | // only stub, no tie
|
---|
329 | target = new String[] {
|
---|
330 | dirname + "_" + filename + getStubClassSuffix()
|
---|
331 | + ".class"
|
---|
332 | };
|
---|
333 | } else {
|
---|
334 | /*
|
---|
335 | * stub is derived from implementation,
|
---|
336 | * tie from interface name.
|
---|
337 | */
|
---|
338 | Class interf = attributes.getRemoteInterface(c);
|
---|
339 | String iName = interf.getName();
|
---|
340 | String iDir = "";
|
---|
341 | int iIndex = -1;
|
---|
342 | int lastDot = iName.lastIndexOf(".");
|
---|
343 | if (lastDot == -1) {
|
---|
344 | // no package
|
---|
345 | iIndex = 0;
|
---|
346 | } else {
|
---|
347 | iIndex = lastDot + 1;
|
---|
348 | iDir = iName.substring(0, iIndex);
|
---|
349 | iDir = iDir.replace('.', File.separatorChar);
|
---|
350 | }
|
---|
351 |
|
---|
352 | target = new String[] {
|
---|
353 | dirname + "_" + filename + getTieClassSuffix()
|
---|
354 | + ".class",
|
---|
355 | iDir + "_" + iName.substring(iIndex)
|
---|
356 | + getStubClassSuffix() + ".class"
|
---|
357 | };
|
---|
358 | }
|
---|
359 | } catch (ClassNotFoundException e) {
|
---|
360 | attributes.log("Unable to verify class " + classname
|
---|
361 | + ". It could not be found.",
|
---|
362 | Project.MSG_WARN);
|
---|
363 | } catch (NoClassDefFoundError e) {
|
---|
364 | attributes.log("Unable to verify class " + classname
|
---|
365 | + ". It is not defined.", Project.MSG_WARN);
|
---|
366 | } catch (Throwable t) {
|
---|
367 | attributes.log("Unable to verify class " + classname
|
---|
368 | + ". Loading caused Exception: "
|
---|
369 | + t.getMessage(), Project.MSG_WARN);
|
---|
370 | }
|
---|
371 | }
|
---|
372 | return target;
|
---|
373 | }
|
---|
374 | }
|
---|
375 | }
|
---|