Mappings
From j2cstranslator
Contents |
What mapping files are ?
Mapping files are the place where you specify how to map (translate or replace) expression from Java to CSharp.</br> Expressions can be :
- package,
- class,
- method,
- field.
Replacements can be :
- a name
- a pattern with "link" (argument, type parameter)
- a completely new expression
- an "order" to remove the expression
- an "order" to change a property of the expression (modifiers, hierarchy, imports clauses, ...)
The translator is provided with a set of configuration files to cover java features (see in sources the configuration/ directory).</br> There is an overload mechanism to allow user to define it's own mapping for an already covered expressions.
How to specify a mapping ?
Via files
Mapping files are xml (or text) file located under translator/configuration/ directory.
Note: xml file will be only supported in the coming version. There is a migration tool to transfrom text file into xml file accessible via "Package Explorer". Right Click on the project you want to migrate mapping file, then "Java2CSharp translator" then "Migrate mapping files". These will create in the same folder as you text mapping file, the new "mappingml" files. Don't forget to remove the old (text) mapping file.
XML file
Available orders:
- comments : Text
- codeReplacement : Text
- format : Text
- modifiers : Element
- hierarchy : Element
- imports : Element
- name : Text
- memberMappingBehavior :
- packageMappingBehavior :
- packageName : Text
- typeParameters : Text
- removeGenerics : boolean
- renamed : boolean
- removeStaticInitializers : boolean
- instanceOfTypeName : Text
- isPartial : boolean
- isRemoved : boolean
- nullable : boolean
- processDoc : boolean
- propertyGet : Text
- propertySet : Text
- genericsIf : Text
- indexerGet : Text
- indexerSet : Text
- covariant : Text
- genericsTest :
- isExcluded : boolean
Categories:
- packages:
- disclaimer:
- javadoc:
- keywords:
- variables:
Schema:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="mappings" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="target">
<xs:complexType>
<xs:sequence>
<xs:element name="comments" type="xs:string" minOccurs="0" />
<xs:element name="format" type="xs:string" minOccurs="0" />
<xs:element name="codeReplacement" type="xs:string" minOccurs="0" />
<xs:element name="modifiers" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="add" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="value" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="remove" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="value" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="hierarchy" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="add" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="remove" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="newSupeClassName" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="imports" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="add" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="remove" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="memberMappingBehavior" type="xs:string" />
<xs:attribute name="packageMappingBehavior" type="xs:string" />
<xs:attribute name="packageName" type="xs:string" />
<xs:attribute name="typeParameters" type="xs:string" />
<xs:attribute name="removeGenerics" type="xs:string" />
<xs:attribute name="renamed" type="xs:string" />
<xs:attribute name="removeStaticInitializers" type="xs:string" />
<xs:attribute name="instanceOfTypeName" type="xs:string" />
<xs:attribute name="isPartial" type="xs:string" />
<xs:attribute name="isRemoved" type="xs:string" />
<xs:attribute name="nullable" type="xs:string" />
<xs:attribute name="processDoc" type="xs:string" />
<xs:attribute name="propertyGet" type="xs:string" />
<xs:attribute name="genericsIf" type="xs:string" />
<xs:attribute name="indexerSet" type="xs:string" />
<xs:attribute name="indexerGet" type="xs:string" />
<xs:attribute name="covariant" type="xs:string" />
<xs:attribute name="genericsTest" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="mapping">
<xs:complexType>
<xs:sequence>
<xs:element name="disclaimer" type="xs:string" minOccurs="0" />
<xs:element name="javadoc" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="tag" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="newName" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="keywords" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="keyword" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="alias" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="variables" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="variable" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="alias" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="packages" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="package" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element ref="target" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="class" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element ref="target" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="constructor" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element ref="target" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="signature" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="method" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element ref="target" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="signature" type="xs:string" />
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="isExcluded" type="xs:string" />
</xs:complexType>
</xs:element>
<xs:element name="field" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element ref="target" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="isExcluded" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="packageName" type="xs:string" />
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="typeParameters" type="xs:string" />
<xs:attribute name="generics" type="xs:string" />
<xs:attribute name="removeGenerics" type="xs:string" />
<xs:attribute name="isRemoved" type="xs:string" />
<xs:attribute name="isExcluded" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="isExcluded" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Example
<!-- -->
<!-- ILOG Java 2 CSharp translator mapping file for project EmptyProject -->
<!-- -->
<mapping>
<!-- -->
<!-- packages -->
<!-- -->
<packages>
<!-- tests.mapmethod.comments -->
<package name="tests.mapmethod.comments">
<class name="DummyClass" packageName="tests.mapmethod.comments">
<method name="myMethod" signature="()">
<target>
<comments>
<![CDATA[///
/// a method
///]]>
</comments>
</target>
</method>
</class>
</package>
<!-- tests.mapmethod.name -->
<package name="tests.mapmethod.name">
<class name="DummyClass" packageName="tests.mapmethod.name">
<method name="myMethod" signature="()">
<target name="Glop"/>
</method>
</class>
</package>
<!-- tests.mapmethod.isExcluded -->
<package name="tests.mapmethod.isExcluded" >
<class name="DummyClass" packageName="tests.mapmethod.isExcluded">
<method name="myMethod" signature="()" isExcluded="true">
</method>
</class>
</package>
<!-- tests.mapmethod.covariant -->
<package name="tests.mapmethod.covariant" >
<class name="DummyClass" packageName="tests.mapmethod.covariant">
<method name="myMethod" signature="()">
<target covariant="pck:MyType"/>
</method>
</class>
</package>
<!-- tests.mapmethod.genericsTest -->
<package name="tests.mapmethod.genericsTest" >
<class name="DummyClass" packageName="tests.mapmethod.genericsTest">
<method name="myMethod" signature="()">
<target genericsTest="%1"/>
</method>
</class>
</package>
<!-- tests.mapmethod.format -->
<package name="tests.mapmethod.format">
<class name="DummyClass" packageName="tests.mapmethod.format">
<method name="myMethod" signature="()">
<target>
<format>
<![CDATA[@0]]>
</format>
</target>
</method>
</class>
</package>
<!-- tests.mapmethod.codeReplacement -->
<package name="tests.mapmethod.codeReplacement">
<class name="DummyClass" packageName="tests.mapmethod.codeReplacement">
<method name="myMethod" signature="()">
<target>
<codeReplacement>
<![CDATA[return true; // comments]]>
</codeReplacement>
</target>
</method>
</class>
</package>
<!-- tests.mapmethod.modifiers -->
<package name="tests.mapmethod.modifiers">
<class name="DummyClass" packageName="tests.mapmethod.modifiers">
<method name="myMethod" signature="()">
<target>
<modifiers>
<add value="internal"/>
<remove value="public"/>
</modifiers>
</target>
</method>
</class>
</package>
</packages>
</mapping>
Text File
pattern or format : You use it when the mapping is clearly non trivial. For example change the order of parameters, or perform a computation. You have reserved character : @ and % . With ‘@n’ you can refer to one of the argument of the method signature for example (note that @0 is used to refer the instance where the call to this method is performed to)
‘%n’ is used for type parameters (when your class is generics).
You have many samples of that in the mapping files embedded in the translation (see subversion repo for that) configuration/java.util.conf for example.
Example: pattern = @0.MyMethod(@2, @1 – 12);
nullable : The one is reserved for “value type” (primitive type + enum and decimal) and allow the translation of the type “int” into “int?” means that you can affect the null value to a nullable int.
You can see the Nullable feature introduced in .NET Framework 2.0.
modifiers : With that one you can change the modifiers for a given class/method/field. The syntax is a “+” to add a modifier and a “-“ to remove the different modifier are comma separated.
Example : modifiers = +public, -private;
Possible value are: public, protected, private, final, virtual, override, internal, partial, sealed, abstract, static, const, new
generation: mark that class/method/field as not generated
remove: remove from import the considered class
rename: rename the class instead of replace the name. This is the only way to actually rename a class.
partial: mark the generated class as partial
memberMappingBehavior: The default behavior for methode name mapping is to “capitalize” (Upper the first letter of each sub package). Setting this option to “none” will remains the method name unchanged.
packageMappingBehavior: The default behavior for package mapping is to “capitalize” (Upper the first letter of each sub package). Setting this option to “none” will remains the package name unchanged.
Beta:
superClass = allow modification of super class declaration
interfaces = allow modification of interfaces
[disclaimer = ...;]
[package javaname [:: csharpName] {
[class javafqName [:: chsarpFQNAme] {
[modifiers = +/- public|protected|final| ...;]
[generation = true*|false;]
[remove = true|false*;]
[rename = true|false*;]
[nullable = true|false*;]
[partial = true|false*;]
[memberMappingBehavior = none | capitalized*;]
[packagemappingBehavior = none | capitalized*;]
[superClass = C#PackageName:C#ClassName;]
[interfaces = +C#PackageName:C#ClassNameToAdd | -JavaPackage:ExistingJavaInterfaceNameToRemove; ]
[constraints = "generic constraints to add";]
[instanceOfTypeName = NameOfTypeToUseWithInstanceOforDotClass; ]
[processDoc = true | false;]
[nestedToInner = true | false;]
[removeStaticInitializers = true | false;]
[remove_using = ;]
[add_using = ;]
method methodName([ParameterType]*) {
[modifiers = +/- public|protected|final| ...;]
[generation = true*|false;]
[name= newName;]
[property_get = propertyName;]
[property_set = ...;]
[indexer_get = ...;]
[indexer_set = ...;]
[covariant = ...;]
[pattern = ...;]
[memberMappingBehavior = none | capitalized*;]
[constraints = ...;]
[codeReplacement = ...;]
[genericsif = ...;]
}
field fieldName {
[modifiers = +/- public|protected|final| ...;]
[generation = true*|false;]
[name= newName;]
[pattern = ...;]
}
}]*
}]*
Example
package java.util :: System.Collections {
class java.util.Vector :: System.Collections:ArrayList {
method (int,int) { pattern = new ArrayList(@1); }
method size() { property_get = Count; }
method isEmpty() { pattern = (@0.Count==0); }
method elements() { pattern = new IteratorAdapter(@0.GetEnumerator()); }
method removeAllElements() { name = Clear; }
method add(int, E) { name = Insert; }
method addElement(E) { name = Add; }
method add(E) { name = Add; }
method remove(Object) { pattern = ILOG.CoreRuleEngine.Collections.Collections.Remove(@0, @1); }
method removeElement(Object) { pattern = ILOG.CoreRuleEngine.Collections.Collections.Remove(@0,@1); }
method removeElementAt(int) { pattern = ILOG.CoreRuleEngine.Collections.Collections.RemoveAt(@0,@1); }
method insertElementAt(E,int) { pattern = @0.Insert(@2,@1); }
method setElementAt(E,int) { indexer_set = [@2] = @1; }
method firstElement() { pattern = @0[0]; }
method elementAt(int) { indexer_get = [@1]; }
method get(int) { indexer_get = [@1]; }
method lastElement() { pattern = @0[@0.Count - 1]; }
method setSize(int) { pattern = @0.RemoveRange(@1,@0.Count-@1); }
method capacity() { property_get = Capacity; }
method ensureCapacity(int) { pattern = @0.Capacity = @1; }
method copyInto(Object[]) { name = CopyTo; }
method clone() { name = Clone; }
method set(int, E) { indexer_set = [@1] = @2; }
};
}
Via comments
- class JavaDoc comments : [[../../code|code]]
- @translator_mapping [:: CsharpFqName] { see class }
- [[../../code|code]]
- method JavaDoc comments : [[../../code|code]]
- @translator_mapping { see method }
- [[../../code|code]]
- field JavaDoc comment : [[../../code|code]]
- @translator_mapping { see field }
- [[../../code|code]]
Example
/**
*
* @translator_mapping { modifiers = +protected, -public; }
*/
public class MappingInComments {
/**
* @translator_mapping { modifiers = -private, +protected; }
*/
private int a = 2;
/**
*
* @return
* @translator_mapping { property_get = Toto; }
*/
public int getToto() {
return a;
}
}
