/* * JacORB - a free Java ORB * * Copyright (C) 1997-2014 Gerald Brose / The JacORB Team. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.jacorb.idl; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; import org.apache.tools.ant.Project; import org.apache.tools.ant.taskdefs.MatchingTask; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.util.GlobPatternMapper; import org.apache.tools.ant.util.SourceFileScanner; /** * This is the idl compile task for using the idl compiler * from the ANT build tool. * * @author Wei-ju Wu */ public class JacIDL extends MatchingTask { private File _destdir; private File _srcdir; private Path _includepath; private int _debuglevel; private boolean _generateir; private boolean _generateincluded; private boolean _parseonly; private boolean _noskel; private boolean _nostub; private boolean _sloppyforward; private boolean _sloppynames; private boolean _sloppyidentifiers; private boolean _nofinal; private boolean _ami_callback; private boolean _force_overwrite; private boolean _unchecked_narrow; private boolean _generateEnhanced; private boolean _generatediistubs; private String _cachePlugin; private String helperCompatLevel; private List _defines = new ArrayList(); private List _undefines = new ArrayList(); private File _compileList[] = new File[ 0 ]; private List _i2jpackages = new ArrayList(); private I2JPackageTagHandler i2jHandler = new I2JPackageTagHandler(); public JacIDL() { _destdir = new File("."); _srcdir = new File("."); _parseonly = false; _generateir = false; _noskel = false; _nostub = false; _generateincluded = false; _nofinal = false; _force_overwrite = false; _ami_callback = false; _unchecked_narrow = false; _generatediistubs = false; _debuglevel = 1; } /** * Set the destination directory. * @param dir the destination directory */ public void setDestdir(File dir) { _destdir = dir; } /** * Set the source directory. * @param dir the source directory */ public void setSrcdir(File dir) { _srcdir = dir; } /** * Set the include path for the idl compiler. * @param path the include path */ public void setIncludepath(Path path) { _includepath = path; } /** * Set the debug level. * @param level the debug level */ public void setDebuglevel(int level) { _debuglevel = level; } public void setHelperCompat(String in) { helperCompatLevel = in; } // **************************************************************** // **** Set the flags // ****************************** /** * Set the flag to generate the interface repository files. * @param flag the flag */ public void setGenerateir(boolean flag) { _generateir = flag; } /** * Set the flag to generate all files. * @param flag the flag */ public void setAll(boolean flag) { _generateincluded = flag; } /** * Set the flag to parse the idl only. * @param flag the flag */ public void setParseonly(boolean flag) { _parseonly = flag; } /** * Set the flag to leave out skeleton generation. * @param flag the flag */ public void setNoskel(boolean flag) { _noskel = flag; } /** * Set the flag to leave out stub generation. * @param flag the flag */ public void setNostub(boolean flag) { _nostub = flag; } /** * Set the flag to use sloppy forwards. * @param flag the flag */ public void setSloppyforward(boolean flag) { _sloppyforward = flag; } /** * Set the flag to use sloppy names. * @param flag the flag */ public void setSloppynames(boolean flag) { _sloppynames = flag; } /** * Set the flag to use sloppy identifiers. * @param flag the flag */ public void setSloppyidentifiers(boolean flag) { _sloppyidentifiers = flag; } /** * Setter for 'nofinal' property that indicates whether generated code should have * a final class definition. * @param flag <code>true</code> for definitions that are not final. */ public void setNofinal(boolean flag) { _nofinal = flag; } /** * Sets the flag to generate AMI callbacks. */ public void setAmi_callback(boolean flag) { _ami_callback = flag; } /** * Sets the flag to overwrite existing files. */ public void setForceOverwrite(boolean flag) { _force_overwrite = flag; } /** * Sets the flag to generated unchecked narrow() calls in stubs */ public void setUncheckedNarrow(boolean flag) { _unchecked_narrow = flag; } /** * Sets the flag to generated enhanced stubs */ public void setGenerateEnhanced (boolean flag) { _generateEnhanced = flag; } public void setGenerateDIIStubs(boolean flag) { _generatediistubs = flag; } public void setCachePlugin(String className) { _cachePlugin = className; } public void seti2jpackagefile(File pkgfile) { packageFileHelper(pkgfile); } // **************************************************************** // **** Nested elements // ****************************** public void addDefine(org.apache.tools.ant.types.Environment.Variable def) { // The variable can only be evaluated in the execute() method _defines.add(def); } public void addUndefine(org.apache.tools.ant.types.Environment.Variable def) { // The variable can only be evaluated in the execute() method _undefines.add(def); } /** * Will be called whenever an i2jpackage nested PCDATA element is encountered. */ public org.jacorb.idl.JacIDL.I2JPackageTagHandler createI2jpackage() { return i2jHandler; } /** * Inner class that will read the i2jpackage tags. * * The format for these will be <code>i2jpackage names="x:y"</code> * @see #createI2jpackage() */ public class I2JPackageTagHandler { /** * Handle the names="packagefrom:packageto" attribute of the i2jpackage element. * @param names the packagefrom:packageto value. */ public void setNames(String names) { addPackage(names); } /** * Handle the equivalent of -i2jpackagefile argument to parser.java * @param pkgfile the file which contains packagefrom:packageto lines */ public void setFile(File pkgfile) { packageFileHelper(pkgfile); } } // ***************************************************************** // Helper for handling i2jpackage tags private void addPackage(String mapping) { // Testing bad format now avoids a System.exit() in parser.java later if (mapping.indexOf(':') < 0) throw new BuildException("i2jpackage mapping format: "+mapping); _i2jpackages.add(mapping); } private void packageFileHelper(File pkgfile) { // Reader code copied from parser's handling of i2jpackagefile - refactor? try { BufferedReader in = new BufferedReader(new FileReader(pkgfile)); String mapping; while ((mapping = in.readLine()) != null) { // Allow/ignore blank lines and comment lines if (mapping.trim().length() > 0 && !mapping.startsWith("#")) { addPackage(mapping); } } in.close(); } catch (IOException e) { throw new BuildException("i2jpackage failure in file "+pkgfile, e); } } /** * The execute() method of the task. * @throws BuildException */ public void execute() throws BuildException { parser myparser = null; parser.initLogging(); if (helperCompatLevel != null) { if (parser.parseGeneratedHelperPortability(helperCompatLevel) < 0) { throw new BuildException("attribute helperCompability has an invalid value: valid values are: deprecated, portable, jacorb. the default is deprecated."); } parser.generatedHelperPortability = parser.parseGeneratedHelperPortability(helperCompatLevel); } // set destination directory if (! _destdir.exists ()) { _destdir.mkdirs (); } parser.out_dir = _destdir.getPath(); // Generate code for all IDL files, even included ones parser.generateIncluded = _generateincluded; // generate interface repository parser.generateIR = _generateir; // parse only parser.parse_only = _parseonly; // no skeletons parser.generate_skeletons = (!_noskel); // no stubs parser.generate_stubs = (!_nostub); // sloppy forwards parser.sloppy = _sloppyforward; // sloppy names parser.strict_names = (!_sloppynames); // sloppy identifiers parser.strict_identifiers = (!_sloppyidentifiers); // nofinal parser.setGenerateFinalCode(!_nofinal); // AMI callback model parser.generate_ami_callback = _ami_callback; // parser.forceOverwrite = _force_overwrite; parser.useUncheckedNarrow = _unchecked_narrow; parser.generateEnhanced = _generateEnhanced; parser.generateDiiStubs = _generatediistubs; if (_cachePlugin != null) { try { parser.setObjectCachePlugin(_cachePlugin); } catch(InstantiationException e) { throw new BuildException(e); } catch(IllegalAccessException e) { throw new BuildException(e); } } // include path if (_includepath != null) { // Check path String includeList[] = _includepath.list(); for (int i = 0; i < includeList.length; i++) { File incDir = project.resolveFile(includeList[ i ]); if (!incDir.exists()) { throw new BuildException("include directory \"" + incDir.getPath() + "\" does not exist !", location); } } GlobalInputStream.setIncludePath(_includepath.toString()); } // Add the i2jpackage values to the parser for (int i = 0; i < _i2jpackages.size(); i++) { parser.addI2JPackage((String) _i2jpackages.get(i)); } // Set the logging priority parser.logger.setLevel(Environment.intToLevel(_debuglevel)); parser.handler.setLevel(Environment.intToLevel(_debuglevel)); // setup input file lists resetFileLists(); DirectoryScanner ds = getDirectoryScanner(_srcdir); String files[] = ds.getIncludedFiles(); scanFiles(files); // *********************************** // **** invoke parser // *********************************** // invoke the parser for parsing the files that were // specified in the task specification try { if (_compileList != null) { for (int i = 0; i < _compileList.length; i++) { // setup the parser String fileName = _compileList[ i ].getPath(); log("processing idl file: " + fileName); GlobalInputStream.init(); GlobalInputStream.setInput(fileName); lexer.reset(); NameTable.init(); ConstDecl.init(); TypeMap.init(); setupDefines(); myparser = new parser(); myparser.parse(); } } } catch (IOException ex) { if (_debuglevel >= 3) { ex.printStackTrace(); } throw new BuildException(ex); } catch (ParseException ex) { if (_debuglevel >= 3) { ex.printStackTrace(); } throw new BuildException(ex); } catch (Exception ex) { if (_debuglevel >= 3) { ex.printStackTrace(); } throw new BuildException(ex); } finally { parser.cleanup(); } } /** * Clear the list of files to be compiled and copied.. */ protected void resetFileLists() { _compileList = new File[ 0 ]; } /** * Scans the directory looking for source files to be compiled. * The results are returned in the class variable compileList */ protected void scanFiles(String files[]) throws BuildException { File file; // TODO: create an own pattern mapper GlobPatternMapper m = new GlobPatternMapper(); m.setFrom("*.idl"); m.setTo("*.java"); SourceFileScanner sfs = new SourceFileScanner(this); File[] newfiles = sfs.restrictAsFiles(files, _srcdir, _destdir, m); _compileList = new File[ newfiles.length ]; for (int i = 0; i < newfiles.length; i++) { log("scan file: " + newfiles[ i ].getPath(), Project.MSG_DEBUG); file = newfiles[ i ]; if (!file.exists()) { throw new BuildException("The input file \"" + file.getPath() + "\" does not exist !"); } _compileList[ i ] = file; } } public File[] getFileList() { return _compileList; } private void setupDefines() { org.apache.tools.ant.types.Environment.Variable prop; String value; for (int i = 0; i < _defines.size(); i++) { prop = (org.apache.tools.ant.types.Environment.Variable) _defines.get(i); value = prop.getValue(); if (value == null) value = "1"; lexer.define(prop.getKey(), value); } /* Standard compiler defines, can be undefined */ lexer.define("JACORB", "1"); lexer.define("_PRE_3_0_COMPILER_", "1"); lexer.define("GIOP_1_1", "1"); lexer.define("GIOP_1_2", "1"); for (int i = 0; i < _undefines.size(); i++) { prop = (org.apache.tools.ant.types.Environment.Variable) _undefines.get(i); lexer.undefine(prop.getKey()); } } }