// **********************************************************************
//
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************
//package Ice.Ant;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.taskdefs.ExecTask;
import org.apache.tools.ant.types.Commandline.Argument;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.Reference;
import java.io.File;
import java.io.FileOutputStream;
/**
* An ant task for slice2freezej. This task extends the abstract
* SliceTask class which takes care of attributes common to all slice
* translators (see SliceTask.java for details on these attributes).
*
* Attributes:
*
* Nested elements:
*
* define - defines a preprocessor symbol
* dict - contains the NAME, KEY TYPE, and VALUE TYPE of a Freeze map.
* index - contains the NAME, CLASS TYPE, MEMBER NAME and optional
* case sensitivity of a Freeze Evictor index.
* dictindex - contains the NAME and optional member name and case
* sensitivity of a Freeze Map index.
*
* Example:
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* The element installs the slice2freezej task.
*/
public class Slice2FreezeJTask extends SliceTask
{
public
Slice2FreezeJTask()
{
}
public void
setTranslator(File prog)
{
_translator = prog;
}
public Dict
createDict()
{
Dict d = new Dict();
_dicts.add(d);
return d;
}
public Index
createIndex()
{
Index i = new Index();
_indices.add(i);
return i;
}
public Dictindex
createDictindex()
{
Dictindex i = new Dictindex();
_dictIndices.add(i);
return i;
}
public void
execute()
throws BuildException
{
if(_dicts.isEmpty() && _indices.isEmpty())
{
throw new BuildException("No dictionary or index specified");
}
//
// Read the set of dependencies for this task.
//
java.util.HashMap dependencies = readDependencies();
//
// Check if the set of slice files changed. If it changed we
// need to rebuild all the dictionnaries and indices.
//
boolean build = false;
java.util.List sliceFiles = new java.util.LinkedList();
for(FileSet fileset : _fileSets)
{
DirectoryScanner scanner = fileset.getDirectoryScanner(getProject());
String[] files = scanner.getIncludedFiles();
for(String file : files)
{
File slice = new File(fileset.getDir(getProject()), file);
sliceFiles.add(slice);
if(!build)
{
//
// The dictionnaries need to be re-created since
// on dependency changed.
//
SliceDependency depend = dependencies.get(getSliceTargetKey(slice.toString()));
if(depend == null || !depend.isUpToDate())
{
build = true;
}
}
}
}
if(!build)
{
//
// Check that each dictionary has been built at least
// once.
//
for(Dict p : _dicts)
{
SliceDependency depend = dependencies.get(getDictTargetKey(p));
if(depend == null)
{
build = true;
break;
}
}
//
// Likewise for indices
//
for(Index p : _indices)
{
SliceDependency depend = dependencies.get(getIndexTargetKey(p));
if(depend == null)
{
build = true;
break;
}
}
}
//
// Add the --dict options.
//
StringBuilder dictString = new StringBuilder(128);
for(Dict d : _dicts)
{
dictString.append(" --dict ");
dictString.append(d.getName());
dictString.append(",");
dictString.append(d.getKey());
dictString.append(",");
dictString.append(d.getValue());
}
//
// Add the --dict-index options.
//
StringBuilder dictIndexString = new StringBuilder(128);
for(Dictindex d : _dictIndices)
{
dictIndexString.append(" --dict-index ");
dictIndexString.append(d.getName());
if(d.getMember() != null)
{
dictIndexString.append(",");
dictIndexString.append(d.getMember());
}
if(d.getCasesensitive() == false)
{
dictIndexString.append(",case-insensitive");
}
}
//
// Add the --index options.
//
StringBuilder indexString = new StringBuilder();
for(Index i : _indices)
{
indexString.append(" --index ");
indexString.append(i.getName());
indexString.append(",");
indexString.append(i.getType());
indexString.append(",");
indexString.append(i.getMember());
if(i.getCasesensitive() == false)
{
indexString.append(",case-insensitive");
}
}
if(!build)
{
log("skipping" + dictString + indexString);
return;
}
//
// Run the translator
//
StringBuilder cmd = new StringBuilder(256);
//
// Add --ice
//
if(_ice)
{
cmd.append(" --ice");
}
//
// Add --underscore
//
if(_underscore)
{
cmd.append(" --underscore");
}
//
// Add --output-dir
//
if(_outputDir != null)
{
cmd.append(" --output-dir ");
cmd.append(_outputDirString);
}
//
// Add include directives
//
if(_includePath != null)
{
String[] dirs = _includePath.list();
for(String dir : dirs)
{
cmd.append(" -I");
if(dir.indexOf(' ') != -1)
{
cmd.append('"' + dir + '"');
}
else
{
cmd.append(dir);
}
}
}
//
// Add defines
//
if(!_defines.isEmpty())
{
for(SliceDefine define : _defines)
{
cmd.append(" -D");
cmd.append(define.getName());
String value = define.getValue();
if(value != null)
{
cmd.append("=");
cmd.append(value);
}
}
}
//
// Add the --dict options.
//
cmd.append(dictString.toString());
//
// Add the --dict-index options.
//
cmd.append(dictIndexString.toString());
//
// Add the --index options.
//
cmd.append(indexString.toString());
//
// Add the --meta options.
//
if(!_meta.isEmpty())
{
for(SliceMeta m : _meta)
{
cmd.append(" --meta " + m.getValue());
}
}
//
// Add the slice files.
//
for(File f : sliceFiles)
{
cmd.append(" ");
String s = f.toString();
if(s.indexOf(' ') != -1)
{
cmd.append('"' + s + '"');
}
else
{
cmd.append(s);
}
}
String translator;
if(_translator == null)
{
translator = getDefaultTranslator("slice2freezej");
}
else
{
translator = _translator.toString();
}
//
// Execute.
//
log(translator + " " + cmd);
ExecTask task = (ExecTask)getProject().createTask("exec");
addLdLibraryPath(task);
task.setFailonerror(true);
Argument arg = task.createArg();
arg.setLine(cmd.toString());
task.setExecutable(translator);
task.execute();
//
// Update the dependencies.
//
if(!sliceFiles.isEmpty())
{
cmd = new StringBuilder(256);
cmd.append("--depend");
//
// Add --ice
//
if(_ice)
{
cmd.append(" --ice");
}
//
// Add --underscore
//
if(_underscore)
{
cmd.append(" --underscore");
}
//
// Add include directives
//
if(_includePath != null)
{
String[] dirs = _includePath.list();
for(String dir : dirs)
{
cmd.append(" -I");
if(dir.indexOf(' ') != -1)
{
cmd.append('"');
cmd.append(dir);
cmd.append('"');
}
else
{
cmd.append(dir);
}
}
}
//
// Add the --dict options.
//
cmd.append(dictString.toString());
//
// Add the --dict-index options.
//
cmd.append(dictIndexString.toString());
//
// Add the --index options.
//
cmd.append(indexString.toString());
//
// Add the slice files.
//
for(File f : sliceFiles)
{
cmd.append(" ");
String s = f.toString();
if(s.indexOf(' ') != -1)
{
cmd.append('"');
cmd.append(s);
cmd.append('"');
}
else
{
cmd.append(s);
}
}
//
// It's not possible anymore to re-use the same output property since Ant 1.5.x. so we use a
// unique property name here. Perhaps we should output the dependencies to a file instead.
//
final String outputProperty = "slice2freezej.depend." + System.currentTimeMillis();
task = (ExecTask)getProject().createTask("exec");
addLdLibraryPath(task);
task.setFailonerror(true);
arg = task.createArg();
arg.setLine(cmd.toString());
task.setExecutable(translator);
task.setOutputproperty(outputProperty);
task.execute();
//
// Update dependency file.
//
java.util.List newDependencies =
parseDependencies(getProject().getProperty(outputProperty));
for(SliceDependency dep : newDependencies)
{
dependencies.put(getSliceTargetKey(dep._dependencies[0]), dep);
}
}
for(Dict d : _dicts)
{
dependencies.put(getDictTargetKey(d), new SliceDependency());
}
for(Index i : _indices)
{
dependencies.put(getIndexTargetKey(i), new SliceDependency());
}
writeDependencies(dependencies);
}
private String
getSliceTargetKey(String slice)
{
//
// Since the dependency file can be shared by several slice
// tasks we need to make sure that each dependency has a
// unique key. We use the name of the task, the output
// directory, the first dictionary or index name and the name of the
// slice file to be compiled.
//
String name;
if(_dicts.size() > 0)
{
name = (_dicts.get(0)).getName();
}
else
{
name = (_indices.get(0)).getName();
}
return "slice2freezej " + _outputDir.toString() + name + slice;
}
private String
getDictTargetKey(Dict d)
{
return "slice2freezej " + _outputDir.toString() + d.getName();
}
private String
getIndexTargetKey(Index i)
{
return "slice2freezej " + _outputDir.toString() + i.getName();
}
private File _translator = null;
public class Dict
{
private String _name;
private String _key;
private String _value;
public void
setName(String name)
{
_name = name;
}
public String
getName()
{
return _name;
}
public void
setKey(String key)
{
_key = key;
}
public String
getKey()
{
return _key;
}
public void
setValue(String value)
{
_value = value;
}
public String
getValue()
{
return _value;
}
}
public class Dictindex
{
private String _name;
private String _member;
private boolean _caseSensitive = true;
public void
setName(String name)
{
_name = name;
}
public String
getName()
{
return _name;
}
public void
setMember(String member)
{
_member = member;
}
public String
getMember()
{
return _member;
}
public void
setCasesensitive(boolean caseSensitive)
{
_caseSensitive = caseSensitive;
}
public boolean
getCasesensitive()
{
return _caseSensitive;
}
}
public class Index
{
private String _name;
private String _type;
private String _member;
private boolean _caseSensitive = true;
public void
setName(String name)
{
_name = name;
}
public String
getName()
{
return _name;
}
public void
setType(String type)
{
_type = type;
}
public String
getType()
{
return _type;
}
public void
setMember(String member)
{
_member = member;
}
public String
getMember()
{
return _member;
}
public void
setCasesensitive(boolean caseSensitive)
{
_caseSensitive = caseSensitive;
}
public boolean
getCasesensitive()
{
return _caseSensitive;
}
}
private java.util.List _dicts = new java.util.LinkedList();
private java.util.List _dictIndices = new java.util.LinkedList();
private java.util.List _indices = new java.util.LinkedList();
}