diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java | 493 |
1 files changed, 493 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java new file mode 100644 index 00000000..bb2cfaab --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/rmic/DefaultRmicAdapter.java @@ -0,0 +1,493 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.tools.ant.taskdefs.rmic; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; +import java.util.Vector; + +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.Rmic; +import org.apache.tools.ant.types.Commandline; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.util.FileNameMapper; +import org.apache.tools.ant.util.StringUtils; + +/** + * This is the default implementation for the RmicAdapter interface. + * Currently, this is a cut-and-paste of the original rmic task and + * DefaultCompilerAdapter. + * + * @since Ant 1.4 + */ +public abstract class DefaultRmicAdapter implements RmicAdapter { + + private Rmic attributes; + private FileNameMapper mapper; + private static final Random RAND = new Random(); + /** suffix denoting a stub file: {@value} */ + public static final String RMI_STUB_SUFFIX = "_Stub"; + /** suffix denoting a skel file: {@value} */ + public static final String RMI_SKEL_SUFFIX = "_Skel"; + /** suffix denoting a tie file: {@value} */ + public static final String RMI_TIE_SUFFIX = "_Tie"; + /** arg for compat: {@value} */ + public static final String STUB_COMPAT = "-vcompat"; + /** arg for 1.1: {@value} */ + public static final String STUB_1_1 = "-v1.1"; + /** arg for 1.2: {@value} */ + public static final String STUB_1_2 = "-v1.2"; + + /** + * option for stub 1.1 in the rmic task: {@value} + */ + public static final String STUB_OPTION_1_1 = "1.1"; + /** + * option for stub 1.2 in the rmic task: {@value} + */ + public static final String STUB_OPTION_1_2 = "1.2"; + /** + * option for stub compat in the rmic task: {@value} + */ + public static final String STUB_OPTION_COMPAT = "compat"; + + /** + * Default constructor + */ + public DefaultRmicAdapter() { + } + + /** + * Sets Rmic attributes + * @param attributes the rmic attributes + */ + public void setRmic(final Rmic attributes) { + this.attributes = attributes; + mapper = new RmicFileNameMapper(); + } + + /** + * Get the Rmic attributes + * @return the attributes as a Rmic taskdef + */ + public Rmic getRmic() { + return attributes; + } + + /** + * Gets the stub class suffix + * @return the stub suffix "_Stub" + */ + protected String getStubClassSuffix() { + return RMI_STUB_SUFFIX; + } + + /** + * Gets the skeleton class suffix + * @return the skeleton suffix "_Skel" + */ + protected String getSkelClassSuffix() { + return RMI_SKEL_SUFFIX; + } + + /** + * Gets the tie class suffix + * @return the tie suffix "_Tie" + */ + protected String getTieClassSuffix() { + return RMI_TIE_SUFFIX; + } + + /** + * This implementation returns a mapper that may return up to two + * file names. + * + * <ul> + * <li>for JRMP it will return *_getStubClassSuffix (and + * *_getSkelClassSuffix if JDK 1.1 is used)</li> + * + * <li>for IDL it will return a random name, causing <rmic> to + * always recompile.</li> + * + * <li>for IIOP it will return _*_getStubClassSuffix for + * interfaces and _*_getStubClassSuffix for non-interfaces (and + * determine the interface and create _*_Stub from that).</li> + * </ul> + * @return a <code>FileNameMapper</code> + */ + public FileNameMapper getMapper() { + return mapper; + } + + /** + * Gets the CLASSPATH this rmic process will use. + * @return the classpath + */ + public Path getClasspath() { + return getCompileClasspath(); + } + + /** + * Builds the compilation classpath. + * @return the classpath + */ + protected Path getCompileClasspath() { + Path classpath = new Path(attributes.getProject()); + // add dest dir to classpath so that previously compiled and + // untouched classes are on classpath + classpath.setLocation(attributes.getBase()); + + // Combine the build classpath with the system classpath, in an + // order determined by the value of build.sysclasspath + + Path cp = attributes.getClasspath(); + if (cp == null) { + cp = new Path(attributes.getProject()); + } + if (attributes.getIncludeantruntime()) { + classpath.addExisting(cp.concatSystemClasspath("last")); + } else { + classpath.addExisting(cp.concatSystemClasspath("ignore")); + } + + if (attributes.getIncludejavaruntime()) { + classpath.addJavaRuntime(); + } + return classpath; + } + + /** + * Setup rmic argument for rmic. + * @return the command line + */ + protected Commandline setupRmicCommand() { + return setupRmicCommand(null); + } + + /** + * Setup rmic argument for rmic. + * @param options additional parameters needed by a specific + * implementation. + * @return the command line + */ + protected Commandline setupRmicCommand(String[] options) { + Commandline cmd = new Commandline(); + + if (options != null) { + for (int i = 0; i < options.length; i++) { + cmd.createArgument().setValue(options[i]); + } + } + + Path classpath = getCompileClasspath(); + + cmd.createArgument().setValue("-d"); + cmd.createArgument().setFile(attributes.getOutputDir()); + + if (attributes.getExtdirs() != null) { + cmd.createArgument().setValue("-extdirs"); + cmd.createArgument().setPath(attributes.getExtdirs()); + } + + cmd.createArgument().setValue("-classpath"); + cmd.createArgument().setPath(classpath); + String stubOption = addStubVersionOptions(); + if (stubOption != null) { + //set the non-null stubOption + cmd.createArgument().setValue(stubOption); + } + + + if (null != attributes.getSourceBase()) { + cmd.createArgument().setValue("-keepgenerated"); + } + + if (attributes.getIiop()) { + attributes.log("IIOP has been turned on.", Project.MSG_INFO); + cmd.createArgument().setValue("-iiop"); + if (attributes.getIiopopts() != null) { + attributes.log("IIOP Options: " + attributes.getIiopopts(), + Project.MSG_INFO); + cmd.createArgument().setValue(attributes.getIiopopts()); + } + } + + if (attributes.getIdl()) { + cmd.createArgument().setValue("-idl"); + attributes.log("IDL has been turned on.", Project.MSG_INFO); + if (attributes.getIdlopts() != null) { + cmd.createArgument().setValue(attributes.getIdlopts()); + attributes.log("IDL Options: " + attributes.getIdlopts(), + Project.MSG_INFO); + } + } + + if (attributes.getDebug()) { + cmd.createArgument().setValue("-g"); + } + + String[] compilerArgs = attributes.getCurrentCompilerArgs(); + compilerArgs = preprocessCompilerArgs(compilerArgs); + cmd.addArguments(compilerArgs); + + logAndAddFilesToCompile(cmd); + return cmd; + } + + /** + * This is an override point; get the stub version off the rmic command and + * translate that into a compiler-specific argument + * @return a string to use for the stub version; can be null + * @since Ant1.7.1 + */ + protected String addStubVersionOptions() { + //handle the many different stub options. + String stubVersion = attributes.getStubVersion(); + //default is compatibility + String stubOption = null; + if (null != stubVersion) { + if (STUB_OPTION_1_1.equals(stubVersion)) { + stubOption = STUB_1_1; + } else if (STUB_OPTION_1_2.equals(stubVersion)) { + stubOption = STUB_1_2; + } else if (STUB_OPTION_COMPAT.equals(stubVersion)) { + stubOption = STUB_COMPAT; + } else { + //anything else + attributes.log("Unknown stub option " + stubVersion); + //do nothing with the value? or go -v+stubVersion?? + } + } + //for java1.5+, we generate compatible stubs, that is, unless + //the caller asked for IDL or IIOP support. + if (stubOption == null + && !attributes.getIiop() + && !attributes.getIdl()) { + stubOption = STUB_COMPAT; + } + return stubOption; + } + + /** + * Preprocess the compiler arguments in any way you see fit. + * This is to allow compiler adapters to validate or filter the arguments. + * The base implementation returns the original compiler arguments unchanged. + * @param compilerArgs the original compiler arguments + * @return the filtered set. + */ + protected String[] preprocessCompilerArgs(String[] compilerArgs) { + return compilerArgs; + } + + + /** + * Strip out all -J args from the command list. Invoke this from + * {@link #preprocessCompilerArgs(String[])} if you have a non-forking + * compiler. + * @param compilerArgs the original compiler arguments + * @return the filtered set. + */ + protected String[] filterJvmCompilerArgs(String[] compilerArgs) { + int len = compilerArgs.length; + List args = new ArrayList(len); + for (int i = 0; i < len; i++) { + String arg = compilerArgs[i]; + if (!arg.startsWith("-J")) { + args.add(arg); + } else { + attributes.log("Dropping " + arg + " from compiler arguments"); + } + } + int count = args.size(); + return (String[]) args.toArray(new String[count]); + } + + + /** + * Logs the compilation parameters, adds the files to compile and logs the + * "niceSourceList" + * @param cmd the commandline args + */ + protected void logAndAddFilesToCompile(Commandline cmd) { + Vector compileList = attributes.getCompileList(); + + attributes.log("Compilation " + cmd.describeArguments(), + Project.MSG_VERBOSE); + + StringBuffer niceSourceList = new StringBuffer("File"); + int cListSize = compileList.size(); + if (cListSize != 1) { + niceSourceList.append("s"); + } + niceSourceList.append(" to be compiled:"); + + for (int i = 0; i < cListSize; i++) { + String arg = (String) compileList.elementAt(i); + cmd.createArgument().setValue(arg); + niceSourceList.append(" "); + niceSourceList.append(arg); + } + + attributes.log(niceSourceList.toString(), Project.MSG_VERBOSE); + } + + /** + * Mapper that may return up to two file names. + * + * <ul> + * <li>for JRMP it will return *_getStubClassSuffix (and + * *_getSkelClassSuffix if JDK 1.1 is used)</li> + * + * <li>for IDL it will return a random name, causing <rmic> to + * always recompile.</li> + * + * <li>for IIOP it will return _*_getStubClassSuffix for + * interfaces and _*_getStubClassSuffix for non-interfaces (and + * determine the interface and create _*_Stub from that).</li> + * </ul> + */ + private class RmicFileNameMapper implements FileNameMapper { + + RmicFileNameMapper() { + } + + /** + * Empty implementation. + */ + public void setFrom(String s) { + } + /** + * Empty implementation. + */ + public void setTo(String s) { + } + + public String[] mapFileName(String name) { + if (name == null + || !name.endsWith(".class") + || name.endsWith(getStubClassSuffix() + ".class") + || name.endsWith(getSkelClassSuffix() + ".class") + || name.endsWith(getTieClassSuffix() + ".class")) { + // Not a .class file or the one we'd generate + return null; + } + + // we know that name.endsWith(".class") + String base = StringUtils.removeSuffix(name, ".class"); + + String classname = base.replace(File.separatorChar, '.'); + if (attributes.getVerify() + && !attributes.isValidRmiRemote(classname)) { + return null; + } + + /* + * fallback in case we have trouble loading the class or + * don't know how to handle it (there is no easy way to + * know what IDL mode would generate. + * + * This is supposed to make Ant always recompile the + * class, as a file of that name should not exist. + */ + String[] target = new String[] {name + ".tmp." + RAND.nextLong()}; + + if (!attributes.getIiop() && !attributes.getIdl()) { + // JRMP with simple naming convention + if (STUB_OPTION_1_2.equals(attributes.getStubVersion())) { + target = new String[] { + base + getStubClassSuffix() + ".class" + }; + } else { + target = new String[] { + base + getStubClassSuffix() + ".class", + base + getSkelClassSuffix() + ".class", + }; + } + } else if (!attributes.getIdl()) { + int lastSlash = base.lastIndexOf(File.separatorChar); + + String dirname = ""; + /* + * I know, this is not necessary, but I prefer it explicit (SB) + */ + int index = -1; + if (lastSlash == -1) { + // no package + index = 0; + } else { + index = lastSlash + 1; + dirname = base.substring(0, index); + } + + String filename = base.substring(index); + + try { + Class c = attributes.getLoader().loadClass(classname); + + if (c.isInterface()) { + // only stub, no tie + target = new String[] { + dirname + "_" + filename + getStubClassSuffix() + + ".class" + }; + } else { + /* + * stub is derived from implementation, + * tie from interface name. + */ + Class interf = attributes.getRemoteInterface(c); + String iName = interf.getName(); + String iDir = ""; + int iIndex = -1; + int lastDot = iName.lastIndexOf("."); + if (lastDot == -1) { + // no package + iIndex = 0; + } else { + iIndex = lastDot + 1; + iDir = iName.substring(0, iIndex); + iDir = iDir.replace('.', File.separatorChar); + } + + target = new String[] { + dirname + "_" + filename + getTieClassSuffix() + + ".class", + iDir + "_" + iName.substring(iIndex) + + getStubClassSuffix() + ".class" + }; + } + } catch (ClassNotFoundException e) { + attributes.log("Unable to verify class " + classname + + ". It could not be found.", + Project.MSG_WARN); + } catch (NoClassDefFoundError e) { + attributes.log("Unable to verify class " + classname + + ". It is not defined.", Project.MSG_WARN); + } catch (Throwable t) { + attributes.log("Unable to verify class " + classname + + ". Loading caused Exception: " + + t.getMessage(), Project.MSG_WARN); + } + } + return target; + } + } +} |