Changes between Initial Version and Version 1 of MapGuideRfc129


Ignore:
Timestamp:
Nov 28, 2012, 7:12:53 AM (11 years ago)
Author:
jng
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • MapGuideRfc129

    v1 v1  
     1
     2= !MapGuide RFC 129 - SWIG/IMake enhancements and enhanced Java wrapper API =
     3
     4This page contains a change request (RFC) for the !MapGuide Open Source project.
     5More !MapGuide RFCs can be found on the [wiki:MapGuideRfcs RFCs] page.
     6
     7
     8== Status ==
     9
     10||RFC Template Version||(1.0)||
     11||Submission Date||29 Nov 2012||
     12||Last Modified||||
     13||Author||Jackie Ng||
     14||RFC Status||draft||
     15||Implementation Status||||
     16||Proposed Milestone||2.5||
     17||Assigned PSC guide(s)||(when determined)||
     18||'''Voting History'''||(vote date)||
     19||+1||||
     20||+0||||
     21||-0||||
     22||-1||||
     23||no vote|| ||
     24
     25== Overview ==
     26
     27This RFC proposes to add enhancments to SWIG/IMake to support an enhanced Java wrapper API as well as supporting the preservation/conversion of doxygen API documentation fragments for Java and .net
     28
     29== Motivation ==
     30
     31The problems with the current Java wrapper API are [http://trac.osgeo.org/mapguide/ticket/9 well documented]:
     32
     33 * Java method names are in UpperCamelCase (verbatim copy from MapGuide's C++ classes) instead of lowerCamelCase
     34 * MgException is a checked exception. All java methods have the "throws MgException" clause forcing the user to either implement a (possibly un-necessary try/catch block) or to add their own "throws MgException" clause in their calling method
     35 * MapGuide collection classes (eg. MgStringCollection) not implementing the java.util.Collection interface
     36 * Lack of integrated javadoc comments in java proxy source files due to doxygen comments being lost in the SWIG build/translation process
     37
     38== Proposed Solution ==
     39
     40To address these issues, modifications will be made to our internal copy of SWIG and IMake to enable the creation of an "enhanced" Java wrapper API
     41
     42=== Add a JavaApiEx project to the WebTier solution ===
     43
     44This is a copy of the JavaApi directory with a set of SWIG macros/customizations/typemaps to facilitiate the implemenation of java.util.Collection and java.util.Iterable for proxy classes that require such interfaces
     45
     46Classes which are currently slated for java.util.Collection support include:
     47
     48 * MgClassDefinitionCollection (as Collection<MgClassDefinition>)
     49 * MgFeatureSchemaCollection (as Collection<MgFeatureSchema>)
     50 * MgPropertyDefinitionCollection (as Collection<MgPropertyDefinition>)
     51 * MgPropertyCollection (as Collection<MgProperty>)
     52 * MgStringCollection (as Collection<java.lang.String>)
     53 * MgLayerCollection (as Collection<MgLayerBase>)
     54 * MgLayerGroupCollection (as Collection<MgLayerGroup>)
     55
     56The following collection classes will not implement the java.util.Collection interface due to disparity in interface and implementation
     57
     58 * MgIntCollection (int is not an object in Java)
     59 * MgBatchPropertyCollection (can't implement as Collection<MgPropertyCollection> due to a different contains() API)
     60
     61Classes which are currently slated for java.util.Iterable support include:
     62
     63 * MgReadOnlyLayerCollection
     64
     65The following classes will have special implementations of equals() and hashCode() needed for item containment logic to properly work in the java.util.Collection API
     66
     67 * MgClassDefinition
     68 * MgFeatureSchema
     69 * MgPropertyDefinition
     70 * MgProperty
     71 * MgLayerBase
     72 * MgLayerGroup
     73
     74Classes that implement java.util.Collection or java.lang.Iterable can be iterated with java's enhanced for loop:
     75
     76{{{
     77MgClassDefinitionCollection classes = ...
     78for (MgClassDefinition clsDef : classes) {
     79    ...
     80}
     81}}}
     82
     83To distinguish this wrapper from the original, this project will output MapGuideJavaApiEx.dll as the JNI glue library and MapGuideApiEx.jar as the Java wrapper API jar.
     84
     85The pre-defined AppThrowable java exception class will now extend from java.lang.RuntimeException, making all subclasses (MgException and co) unchecked exceptions
     86
     87=== Modify swig to support 2 new java-specific command-line options (-mgjavacasing and -mgjavanothrow) ===
     88
     89With the -mgjavacasing option given, all method names will be re-written with the first letter lower-cased by SWIG
     90
     91With the -mgjavanothrow option given, the "throws MgException" clause is omitted from all Java method declarations
     92
     93The JavaApi project will invoke SWIG as before. The JavaApiEx project will invoke SWIG with these 2 new options
     94
     95=== Use the SWIG modifier directives as a means of transplanting documentation / deprecation ===
     96
     97Using the `%typemap(javaclassmodifiers)` and `%javamethodmodifiers` directives (for .net, this is `%typemap(csclassmodifiers)` and `%csmethodmodifiers`), we can attach documentation blocks and any attributes to our Java/C# proxy class methods
     98
     99For example a deprecated API like the [http://trac.osgeo.org/mapguide/wiki/MapGuideRfc9 blank MgMap constructor] can be decorated like so
     100
     101{{{
     102//Java 
     103%javamethodmodifiers MgMap::MgMap() %{/** 
     104* This constructor is deprecated. Use MgMap(MgSiteConnection) instead 
     105*/   
     106@Deprecated public%}
     107 
     108//C# 
     109%csmethodmodifiers MgMap::MgMap() %{///<summary> 
     110/// This constructor is deprecated. Use MgMap(MgSiteConnection) instead 
     111// </summary> 
     112[Obsolete(\"This API is deprecated\")] public%} 
     113}}}
     114
     115Which will cause SWIG to generate the following proxy class method declarations
     116
     117{{{
     118//Java   
     119public class MgMap   
     120{   
     121    /** 
     122     * This constructor is deprecated. Use MgMap(MgSiteConnection) instead 
     123     */ 
     124    @Deprecated public MgMap() {   
     125    ...   
     126    }   
     127}   
     128
     129//C#   
     130public class MgMap   
     131{   
     132    ///<summary>
     133    /// This constructor is deprecated. Use MgMap(MgSiteConnection) instead 
     134    ///</summary>
     135    [Obsolete("This API is deprecated")] public MgMap() {   
     136        ...   
     137    }   
     138}   
     139}}}
     140
     141In addition to documentation, this also gives us the ability to transfer C++ API deprecation intent to the target languages as well, allowing for csc and javac to trigger compiler warnings regarding use of deprecated APIs.
     142
     143As long as the deprecated C++ API(s) are marked up with the doxygen \deprecated directive, they will properly transfer across as @Deprecated in Java and ObsoleteAttribute in .net
     144
     145=== Modify IMake to collect doxygen fragments of input headers and output the translated version in the target language ===
     146
     147It is obviously impractical to manually write out these SWIG modifier directives by hand. So we'll modify IMake to do this for us.
     148
     149IMake already does some sort of documentation collection when it writes out the constants source files for PHP/Java/.net. Unfortunately this is a verbatim doxygen dump which renders these blocks un-usable when used for auto-completion within an IDE
     150
     151So IMake will be modified as follows:
     152
     153 * Retain the documentation collection logic when the input file is not Constants.xml
     154 * Add methods to convert the collected doxygen documentation to the target language's documentation format (JavaDoc for Java, XML documentation for .net)
     155 * Write these converted fragments out as the aforementioned SWIG modifier directives for the target language.
     156
     157These IMake changes only apply for Java and .net. See implications
     158
     159=== Update the *ApiGen.xml files ===
     160
     161All these files require a new DocTarget element, which specifies the output file that IMake will write these SWIG modifier directives to.
     162
     163This file is %include'd into the MapGuideApi.i (the split one for .net) that IMake generates for SWIG, allowing for the documentation to be transferred over to the proxy classes of the target language
     164
     165=== Modify the .net and Java API build process ===
     166
     167The nmake files for the .net API will be modified so that the csc.exe call includes the /doc parameter. Allowing for Visual Studio intellisense files to be created for each OSGeo.MapGuide assembly
     168
     169The JavaApi and JavaApiEx pre-build events will be modified to include an extra step to build a -source jar file, allowing for similar integrated auto-complete API documentation in the major Java IDEs
     170
     171All of the above changes have been implemented in [http://trac.osgeo.org/mapguide/browser/sandbox/jng/swig-java this sandbox]. Upon adoption of this RFC, the changes in this sandbox will be merged back into the trunk code stream.
     172
     173== Implications ==
     174
     175The existing API wrappers (including the existing Java one) are not affected by these changes.
     176
     177In fact for some languages (Java/.net), they will be getting the extra benefit of integrated API documentation and compiler warnings on use of deprecated APIs
     178
     179This RFC has zero effect (positive or negative) on the PHP wrapper. This is due to SWIG not generating any source PHP files for PHP proxy classes, so there is no actual target to drop in the converted doxygen fragments. Also there is no official way to document PHP code, so trying to bring these same integrated API documentation benefits over to PHP is currently a fruitless endeavour.
     180
     181The DoxyTransform build tool which is currently employed to convert doxygen API documentation to Visual Studio intellisense xml files will be removed as this RFC renders that tool obsolete, and this RFC supports API documentation transfer to both .net and Java instead of just .net
     182
     183For the "enhanced" Java wrapper, the conversion of method names to lowerCamelCase has exposed some API naming conflicts:
     184
     185 * The converted MgException.getStackTrace() conflicts with java.lang.Throwable.getStackTrace()
     186 * The converted MgPropertyDefinition.delete() conflicts with the SWIG-generated delete() method for finalization
     187 * The converted MgClassDefinition.delete() conflicts with the SWIG-generated delete() method for finalization
     188 * The converted MgFeatureSchema.delete() conflicts with the SWIG-generated delete() method for finalization
     189 * The converted add() method of any MapGuide collection class conflicts with the add() method as specified in the java.util.Collection interface (MapGuide's add() returns void, java.util.Collection's add() returns boolean)
     190
     191Since this "enhanced" Java wrapper will be a new wrapper API, there is no compatibility history to deal with unlike the other wrappers so as a result it is much safer and easier to rename the conflicting methods in this enhanced wrapper than to rename the conflicting APIs in the C++ classes (as was the case for [wiki:MapGuideRfc89])
     192
     193The conflicting methods will be renamed in the wrapper as so:
     194
     195 * MgException::getStackTrace() will become MgException.getExceptionStackTrace()
     196 * MgPropertyDefinition.delete() will become MgPropertyDefinition.markAsDeleted()
     197 * MgClassDefinition.delete() will become MgClassDefinition.markAsDeleted()
     198 * MgFeatureSchema.delete() will become MgFeatureSchema.markAsDeleted()
     199 * The add() method of any MapGuide collection class implementing java.util.Collection will become addItem()
     200
     201The Java variant of the AJAX viewer will still use the existing Java wrapper. There are no plans in this RFC to convert the Java AJAX viewer to use the enhanced Java wrapper. It is envisioned that this enhanced Java wrapper will be made available in the 2.5 timeframe as a "developer preview" option. Whether this will replace the existing Java wrapper will be the scope for a future RFC.
     202
     203== Test Plan ==
     204
     205Add a java test application to exercise the classes in the enhanced java wrapper that implement java.util.Collection and java.lang.Iterable
     206
     207Test/verify functionality of existing viewers in both Windows/Linux to confirm the SWIG/IMake changes have no adverse effects on the existing wrapper APIs
     208
     209== Funding / Resources ==
     210
     211Community