Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Wednesday, 15 December 2021

MapGuide and log4shell

The log4shell vulnerability has been making the rounds across the tech space and since MapGuide has Java support, I did a check of our MGOS 3.1.2 and current 4.0 preview installation layouts to see if MapGuide is affected.

MapGuide's Java support comes in the form of:

  • Bundling the Apache Tomcat web server
  • Providing a Java language binding to the MapGuide API in the form of a consumable jar archive.
None of these components carry log4j as a dependency. No log4j jar archives are present in any MGOS installation.

Therefore, you are not affected by log4shell. Everything is good!

Naturally, if your Java-based MapGuide application running on top carries the log4j dependency, you should check if the version you're consuming is affected by log4shell and upgrade that dependency to a non-vulnerable version.

Wednesday, 11 July 2018

Introducing: New experimental bindings for the MapGuide API

I haven't been quiet on the MapGuide front. I've just been deeply entrenched in my lab conducting an important experiment whose results are finally coming into fruition that I am back here to make this exciting announcement.

That experiment was: Can we generate bindings for the MapGuide API using a vanilla version of SWIG? Yes we can!

Background

This is an important question that we needed an answer for and we wanted that answer to be "Yes". 

We currently provide bindings for the MapGuide API in:
  • Java
  • PHP 5.x
  • .net (full framework)
However, we currently use an ancient and heavily modified version of SWIG, whose unclear audit trail of modifications and changes means that being able to support newer versions of PHP (ie. PHP 7.x) or variants of .net like .net Core is nigh-impossible, which puts us in a bit of a pickle because:
  • PHP 5.6 (our current bundled version of PHP) will be end-of-life on December 2018. Bundling and targeting an EOL version of PHP is not a good look. To bundle the current version of PHP (7.x) we need to be able to generate a compatible PHP extension for it. We can't do that with current internal copy of SWIG as the zend extension APIs have massively breaking changes from PHP5 to PHP7.
  • .net Core is where the action is at in the .net space, and not having a presence in this space diminishes our story of being able to build MapGuide applications in .net because as time goes on, that definition of ".net" will assume to mean both the (windows-only) full framework and (cross-platform) .net core.
  • We may want to add support for additional programming languages in the future. Can't do it with our super-modified copy of SWIG again because of the unclear history of changes made to this tool.
Given these factors, and the untenable situation we currently find ourselves in technology-wise, we needed to explore the possibility of generating the bindings using a vanilla (un-modified) version of SWIG. If we're going to go vanilla, we want the latest and greatest, which supports generating bindings for PHP7, and can support .net core with the right amount of SWIG typemap elbow-grease, so all the more motivation to get this working!

What we now have

2 months since the decision to embark on this journey, the mission to get functional MapGuide bindings using vanilla SWIG has been a success! We now have the following bindings for the MapGuide API:
  • A Java binding modeled on the non-crufty official Java binding. Requires Java 7 or higher.
  • A (currently windows-only) PHP extension for PHP 7.1
  • A netstandard2.0-compatible binding for .net that works on both .net Core and full framework and is also cross-platform for platforms where both .net Core and official MapGuide binary packages are available for. For Linux, that means this .net binding works in Ubuntu 14.04 64-bit (where .net Core also has packages available). The nuget package for this binding is fully self-contained and includes the necessary native dependencies (both 32 and 64-bit) needed for the .net library to work. For .net full framework, it includes an MSBuild .targets file to ensure all the required native dependencies are copied out to your application's output directory.
Where to get it

You can grab the bits from the releases page of the mapguide-api-bindings GitHub repo.

For .net, you will have to setup a local package source and drop the nuget package there in order to consume in your library/application.

You will need MapGuide Open Source 3.1.1 installed as this is the only version of MapGuide I am generating these bindings for and testing against. Please observe the current supported platform matrix to see what combinations of technology stacks work with this new set of bindings. Please also observe the respective notes on the .net, PHP and Java bindings to observe what changes and adjustments you need to make in your MapGuide application should you want to try out these bindings.

Sample applications (to make sure this stuff works)

As proof that these bindings work, here's a sample asp.net core application using the new MapGuide .net binding. As a testament to what targeting .net Core gives us, you could bypass building the sample application from source and perhaps give the self-contained package a go. Thanks to the powerful publishing capabilities provided by the dotnet CLI, we can publish a self-contained .net core application with zero external dependencies. In the case of this sample application, you can download the zip, extract it to a windows or Ubuntu 14.04 64-bit machine with a standard MapGuide Open Source 3.1.1 install, run the MvcCoreSample executable within, go to http://localhost:5000 and your MapGuide application is up and running!




For Java and PHP, I'm still cooking up some sample applications in the same vein as the asp.net core one (ie. Porting across the MapGuide Developer's Guide samples), but for now the only verification that these bindings work is that our current binding test suite run to completion (with some failures, but these failures are known failures that are also present in our current bindings).

Where to from here?

I intend for the mapguide-api-bindings project to serve as an incubation area where we can iron out any show-stopping problems before planning for the eventual inclusion into MapGuide proper and supplementing (and in the case of PHP, replacing) our current bindings because eventually, we have to. We cannot keep bundling and targeting PHP 5.x forever. We need to be able to target newer versions of these programming languages, and maybe in some cases new programming languages.

mapguide-api-bindings project repo
asp.net core sample application repo

Friday, 26 July 2013

About that AS YET UN-ANNOUNCED PROJECT

Ok, I might as well unveil this thing in case people start wondering what the hell I was talking around 9 months ago.

The AS YET UN-ANNOUNCED PROJECT is mapguide4j

What was (is) mapguide4j?

mapguide4j was an experiment of mine to dogfood the MapGuide Java wrapper API and test the feasibility of the following things:

1. The feasibility of the Java wrapper to the MapGuide API

The MapGuide Java wrapper is a bit of an unknown quantity. All we knew is that Java ranked the least popular of the 3 development environments in that poll some time ago. Nobody I know has actually showcased a MapGuide application built with the Java wrapper API. So why would this be the case?

  • Was Java just not popular enough?
  • Was the Java wrapper un-reliable?
  • Was the environment setup just too cumbersome?

Despite my reservations about the Java language (which are still true when building this thing), the Java platform is still a major player in the server/enterprise space. The fact that some of the most popular geospatial software written in Java is proof the language and platform are not dying anytime soon.

Could it be the reliability? Possibly. We knew that before the 2.4 release of MapGuide Open Source, this wrapper was leaking memory like a bursting dam. If every "new MgClassName()" statement causes an irrecoverable memory-leak, then it would be no surprise that application reliability/stability would go down the drain

Could it be the cumbersome environment setup? Most likely. The current documentation doesn't really tell you how to actually develop a MapGuide application in Java. Hey, I'd improve this part of the documentation if I myself actually knew but I don't so I am just as clueless as you lot :). Other development environments are easy and well-defined:

  • .net: Start Visual Studio. Make a new ASP.net application, reference your MapGuide assemblies (or pull them down with nuget) and away you go.
  • PHP: Make a new folder under your www directory, start creating/editing your PHP files with your favourite text editor and away you go.
  • Java: ???

What if you're using Eclipse? Netbeans? IntelliJ IDEA? What do you do? I have no idea!

So yeah, building a MapGuide application in Java is fraught with many question marks about development workflow and reliability, something that we hoped to answer (at least partially) with the mapguide4j project.

2. The feasibility of building a MapGuide Web Tier in a high-level language free of Apache / IIS / Tomcat

Though mapguide4j's focus is on the MapGuide Java wrapper API, the question equally applies to .net and PHP. The default Web Tier ties into Apache or IIS and thus any MapGuide applications you build has to tie into Apache or IIS as well. This default setup can hamper some types of MapGuide applications you want to build, which mapguide4j turned out to be one of these special cases.

3. A truly portable Web Tier in a high-level language

If our fully managed Web Tier was done in .net then you're realistically only gonna be able to run it only on Windows which is not what we want. We wanted the ability to have this Web Tier work on both Windows and Linux in a high level language, so it was either PHP or Java. PHP had the Apache dependency, whereas Java does not (depending on the choice of framework we want to use).

4. Getting re-acquainted with Java

My Java skills were rusty. So mapguide4j was also a convenient exercise in getting re-acquainted with this language (and everything about the language that absolutely annoys me :))

mapguide4j overview

Ok, so I didn't really answer the "what" about mapguide4j (more like the "why"). So I'll answer that here.

mapguide4j, from a high level view can be thought of as a 100% Java version of the MapGuide Web Tier, which currently consists of:
  • The mapagent http interface.
  • The AJAX viewer
  • A REST interface to the MapGuide API
mapguide4j was a testbed for exploring ways to improve one of my perceived shortcomings of MapGuide: The ability to be a powerful geospatial web service platform. Sure we could've done this in C++ like GeoREST, but we get things done much quicker in a higher-level language like Java.

mapguide4j was built on top of the Play Framework (v2.0.4) which was chosen as the Java web application framework of choice for the following reasons:
  • It was easy to pick up and play (pun intended). The only required knowledge was Java. No need to understand Servlets, EJBs, JSPs, and every other Java technology/framework with a 3 letter acronym.
  • Simple installation and deployment.
  • Play uses its own fully self-contained high performance http web server, enabling us to have a fully portable and self-contained Web Tier in 100% Java, provided we had the ability to fully replicate the functionality of the mapagent http interface, which turned out to be true. No need to integrate with Apache or IIS, our Play-based mapguide4j can stand on its own with near zero configuration.
  • Play supports hosting within Apache/Tomcat if we need to use Apache/Tomcat as the front-end server.
mapguide4j is basically the current MapGuide Web Tier + lots of extra web services. Or so that was the plan.

So let's cover the various bits of the mapguide4j Web Tier.

mapagent/AJAX Viewer

This was the most crucial piece of the Web Tier. We needed a mapagent-compatible http interface so that client applications like Maestro can operate against mapguide4j with no modifications, and the quickest way to verify that we have a working mapagent is to bring across the AJAX viewer as well.

The first attempt at replicating the mapagent was to painstakingly map each http operation to its respective implementation (as I pictured it in my mind) using what's available in the MapGuide API. Of course, we then hit the problem of some key viewer operations that cannot be implemented this way. This was when I discovered the true purpose of MgHttpRequest and MgHttpResponse which then lit the proverbial light-bulb and made replicating the http mapagent dead simple.

The AJAX viewer was a simple transplant of the JSP code in the existing Java AJAX viewer to fit within the MVC paradigm of the Play Framework. It does 90% of what the existing AJAX viewer does (the missing 10% is esoteric commands and functionality that's not really used or not implemented, which anyone interested will have to fill in the blanks later on).

The end result is we have a 90% functional AJAX viewer within the Play Framework with a fully-compatible mapagent that can serve requests from existing http client applications like Maestro with little/no compatibility problems.

REST interface

This is where the bulk of the what's unique about mapguide4j lies in. The REST-ful interface is modeled on previous discussions about a theoretical REST-ful web service for MapGuide. If you're wondering if we're duplicating functionality that already exists in GeoREST, we're not actually.

GeoREST is about REST-ification of individual MapGuide Feature Sources and FDO connections. mapguide4j's REST interface is about the REST-ificiation of the mapagent endpoint itself, to be able to tap into a similar set of operations and services in a REST-ful manner through clean, well-defined URLs, where standard HTTP verbs (POST, GET, PUT, DELETE) conceptually map to creation/reading/updating/deletion of associated repository and feature data.

So to illustrate how this works we'll illustrate with the Sheboygan dataset. Here's the resource structure for reference


The mapguide4j REST interface resides under the URL of http://localhost:9000/mapguide/rest

All REST-ful URLs are relative to this base URL. All URL access require a session id parameter passed in or passing standard http authentication

The mapguide4j REST interface has several base URLs under the main base URL:
  • Site Repository access: http://localhost:9000/mapguide/rest/library
  • FDO Provider Registry: http://localhost:9000/mapguide/rest/providers
  • Coordinate System Catalog: http://localhost:9000/mapguide/rest/coordsys
  • Site Admin: http://localhost:9000/mapguide/rest/site
Example REST URLs

MapGuide resource ids already follow a pseudo URI syntax, so the restful URL to a given resource is simply tacking on the path component of the resource and then tacking on various suffixes depending on the desired representation we want back.

So for example, if we wanted a resource listing for a folder, we tack on a /list suffix which will return an XML response by default. For example, if we wanted to list the resources under the root directory, the request would be like this

GET http://localhost:9000/mapguide/rest/library/list

We can tack on specific file extensions for specific representations, so the above request can also be represented as

GET http://localhost:9000/mapguide/rest/library/list.xml



For JSON the request would be:

GET http://localhost:9000/mapguide/rest/library/list.json



List representations are also available in HTML

GET http://localhost:9000/mapguide/rest/library/list.html

It is through the HTML representation that allows us to have a basic rudimentary repository browser to navigate through the repository in the web browser



The HTML representation is also a convenient way to "explore" the other various representations as they are all conveniently hyperlinked for you.

For accessing individual resource content, we tack on a /content suffix. For example if we wanted the resource content of Library://Samples/Sheboygan/Data/Parcels.FeatureSource the request would look like

GET http://localhost:9000/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/content

Again, we can plug in the desired file extension for certain representations

GET http://localhost:9000/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/content.xml



GET http://localhost:9000/mapguide/rest/library/Samples/Sheboygan/Data/Parcels.FeatureSource/content.json



We'll stop right here because going through all the possible URLs would take forever. But hopefully this gives you the idea of what can be done through this REST interface. You can see example URLs through this link or through exploring the HTML representation list views that provides hyperlinked URLs to all the various supported representations.

Basically most resource and feature service APIs can be accessed via the REST interface

... and that's when everything stopped and ground to a halt.

I haven't actually touched this project in months, so rather than leave this project languishing into nothingness, I'm decided to re-purpose mapguide4j as a giant piece of sample code that should hopefully give you some ideas as to what you can do with the MapGuide API in Java.

You can check out mapguide4j at my GitHub. Unlike my other open source handiwork, I've picked the most liberal OSS license (MIT) I won't be doing anything more with this code. Feel free to fork/clone/hack it to your heart's content.

For me, I achieved what I wanted to know with mapguide4j. It proved to me that it was indeed possible to build some powerful web services on top of the MapGuide API and more importantly, to do it all in Java.

Wednesday, 3 April 2013

Not all is quiet on the mg-desktop front


Looks like it's working so far!

Wednesday, 28 November 2012

Improving the MapGuide API Documentation (part 3)

This post has a bit of a misleading title (it's more the wrapper API we're improving than the documentation) but whatever, we'll run with it.

So just to explain the previous screenshot (and probably my java-related tirades on Twitter and Google Plus for anyone who happens to follow me there) ...

That screenshot was "visual" confirmation of some MapGuide API wrapper enhancement work I've been doing to address some of the pain points of using the MapGuide API (namely Java, but this work has some cross-pollinating benefits for .net as well)

The Problem

For the 15 people in the room who actually use the MapGuide Java wrapper API in its current form (I kid, though it could possibly be true), you've probably had to deal with these annoying issues:
  • The Java proxy of MgException being a checked exception. Thus having to pollute your java code with "throws MgException" in calling methods or having to try/catch an exception that probably isn't thrown 99% of the time and if you do catch it, you're probably just gonna log or display that exception anyway.
  • Java class method naming being a verbatim transplant of their C++ counterparts (ie. They're in UpperCamelCase instead of lowerCamelCase)
  • Java proxies of MapGuide collection classes being verbatim wrapper classes, and not behaving like a Java collection. You can't even for-each through these collections due to key java interfaces not being implemented in the proxy classes.
  • Needing to have the web-based API reference on hand as doxygen commentary is lost in translation to the target language. Auto-complete in your Java IDE of choice gives you no documentation, because none is transferred across.
  • Needing to have the web-based API reference on hand to also find out if a given class or method is deprecated, because nothing in the proxy classes will tell you that to trigger any compiler warnings
  • Hardcore memory leaks in the Java wrapper
Most of the above points, pretty much summed up in this 6-year old ticket.

Though the memory leaks were plugged for the 2.4 release, the other problems are still present. Despite my own reservations about Java (the language), Java (the platform/ecosystem) can't be ignored. Just because we're using SWIG to churn out bindings to 3 different languages doesn't mean we can't do some tweaking here and there for a given language. We already do this for .net (to support properties and serializable exceptions), so why not give the Java wrapper some love as well?

The Solution

For those who are wondering how we actually build bindings to the MapGuide API in 3 different languages, here's a high-level overview:



As already mentioned, SWIG is the tool used to generate the language bindings to the MapGuide API, but in order to enforce some level of encapsulation in the wrapper APIs (because there's C++ internals in some MapGuide API classes that shouldn't be exposed in the wrapper classes), we run a custom pre-processor (IMake.exe) through the MapGuide C++ headers to generate a "sanitized" input file for SWIG to do its thing.

If you ever look at a any MapGuide C++ header and wonder what those PUBLISHED_API, INTERNAL_API and EXTERNAL_API markers are for, they are for IMake to generate an encapsulated view of that particular class for SWIG. Similarly, the __get and __set markers you see at the end of some method declarations are hints to IMake to generate .net properties for that particular method.

The same IMake tool is also used to generate the constants.php for PHP and the necessary constants source files for .net and Java

The solution consists of 3 parts:
  • Modifying SWIG to support our java-specific requirements
  • (Ab)using some SWIG directives for purposes beyond their original scope
  • Modifying the IMake preparation tool to take advantage of these (ab)used SWIG directives
Modifying SWIG

This part was simpler than I thought. The SWIG source code was not as hostile as I originally thought and hacking the java module to support what we need was relatively straightforward. SWIG was basically modified to support 2 optional java-only flags:
  • To omit the "throws MgException" clause in any java method generated
  • To output java methods in lowerCamelCase. Since all MapGuide API C++ methods are guaranteed to be in UpperCamelCase, this is a simple case of lower-casing the first letter of each method that SWIG writes out.
These flags are optional, because if we are going to provide a new enhanced Java wrapper API, we'd still want to keep the existing one around for compatibility purposes, with the enhanced wrapper being an opt-in choice.

(Ab)using SWIG directives

The directives in question are:
  • %typemap(javaclassmodifiers) (.net equivalent is %typemap(csclassmodifiers))
  • %javamethodmodifiers (.net equivalent is %csclassmodifiers)
Normally, these 2 directives are used to alter class/method visibility of the respective generated proxy classes

For example, if we apply this SWIG directive:

 %javaclassmodifiers MgMap::MgMap() "protected"  

We get the following java proxy class method declaration:

 public class MgMap
 {  
   ...  
   protected MgMap()  
   {  
     ....  
   }  
 }  

Similarly if we apply this typemap:

 %typemap(javaclassmodifiers) MgMap "private"  

We get the following java proxy class declaration:

 private class MgMap  
 {  
   ...  
 }  

The trick with these directives is that that SWIG does no validation of the visibility string, meaning we can put any arbitrary content in there, say things like javadoc comments and annotations (or XML comments and attributes in .net). In fact, this technique is what the authors of SWIG recommend as a way of being able to document your proxy classes

So since we all know that the blank MgMap constructor is a deprecated API that you should stay away from. We can specify SWIG directives like this:

 //Java  
 %javamethodmodifiers MgMap::MgMap() %{/**  
  * This constructor is deprecated. Use MgMap(MgSiteConnection) instead  
  */   
 @Deprecated public%}  
 //C#  
 %csmethodmodifiers MgMap::MgMap() %{///<summary>  
 /// This constructor is deprecated. Use MgMap(MgSiteConnection) instead  
 // </summary>  
 [Obsolete(\"This API is deprecated\")] public%}  

Which will then turn into the following proxy class method declarations when SWIG processes them:

 //Java   
  public class MgMap   
  {   
   /**  
   * This constructor is deprecated. Use MgMap(MgSiteConnection) instead  
   */  
   @Deprecated public MgMap() {   
    ...   
   }    
  }   
  //C#   
  public class MgMap   
  {   
   ///<summary>
   /// This constructor is deprecated. Use MgMap(MgSiteConnection) instead  
   ///</summary>
   [Obsolete("This API is deprecated")] public MgMap() {   
    ...   
   }    
  }   

Meaning with these directives, it is now possible for us to not only pass down (converted) doxygen comments, but also pass down deprecation intent as well, because sometimes an API reference is not enough to tell you something is deprecated. You ideally want csc or javac to throw a compiler warning at your face while compiling against the wrapper API library to truly drive the point home that you should not be using this class or method.

Modifying IMake

So we have the means to transfer documentation and deprecation from the C++ classes, but surely we aren't going to manually transcribe the documentation fragments of the hundreds of classes that are in the MapGuide API? Of course not!

The IMake tool already does a pass through all the MapGuide C++ headers. And if you look at the constants.php generated by IMake, you can see that it does pick up and collect doxygen commentary along the way (albeit dumped verbatim into the target language, making it un-usable as javadoc or .net documentation). So the IMake tool was modified to do the following:
  • Translate these collected doxygen fragments to their javadoc or .net counterparts
  • Write these fragments out as the aforementioned SWIG directives for the target language
Other assorted codegen magic

Sadly, Java being the dinosaur of a programming language that it is compared to C# (in my opinion), does not support something similar to partial classes, which would've made augmentation of generated java proxy classes so much simpler, so in order to add java.util.Collection and java.util.Iterable support, we have to once again look at SWIG directives for ways we can augment the generated java classes.

Fortunately SWIG also supports a javacode typemap, that basically allows us to inject vast bodies of java code into our SWIG generated java proxy classes. This allows us to easily implement java.util.Collection support for the collection classes and java.lang.Iterable support allowing for these objects to be iterated in a for-each fashion.

In a way, these SWIG directives are kind of like pseudo-templates for Java, minus the pain of having to deal with the half-assed Java generics, as their way of implementing generics completely blows (I can't make an array of generic type T? GTFO!)

The MgException class (from which all MapGuide exceptions inherit from) extends a pre-defined java AppThrowable class, which itself extends from Exception. As a result, all proxy exceptions are checked as a result. Making these exception classes un-checked as a simple case of re-basing the AppThrowable class to extend from RuntimeException instead.

The End Result

So how well do these changes fare? We can verify by running javadoc against the generated proxy Java class source files. Have another look at that same screenshot of the javadoc from our "enhanced" Java wrapper API:


What can we see here?
  • Java method names are now properly named in lowerCamelCase
  • Doxygen \deprecated markers have been properly translated to @Deprecated annotations (and ObsoleteAttribute in .net)
And also a simple reminder from IMake that we've still got lots of room for improvement in the API documentation content



If we dive down to the method level, here's what we currently have in doxygen:


And here's what gets transplanted to javadoc


As you can see, most of the key doxygen directives have matching/compatible javadoc equivalents allowing for easy conversion by the IMake tool.

All MapGuide exceptions are now un-checked, as they extend RuntimeException


For .net, we get the same result as going through the DoxyTransform tool. In fact, this API enhancement work will render the existing .net documentation approach obsolete, as this approach does the same thing but supports multiple target languages.

So the javadoc output is proof that we have working transplanted documentation, now comes the important bit: making this documentation easily consumable from within a Java IDE, which is incidentally where I'm currently scratching my head. 

What is the official/recommended way to consume Javadoc in a Java IDE (Eclipse, Netbeans, etc)? Is there an official way? Or does each IDE have its own way? I'd appreciate some pointers from someone more knowledgeable in Java tooling than myself. Feel free to comment below.

At the moment, from what I can gather there's 2 ways to bundle up this documentation for consumption within a Java IDE:
  • Pack the java proxy class source files into a separate -sources jar file
  • Pack the javadoc documentation files into a separate -javadoc jar file 
I tried both approaches through IntelliJ IDEA and it seems to pick up both forms:

Here's the result of ctrl+Q with the -sources jar



And the result of ctrl+Q with the -javadoc jar


But I'd still prefer to only have to choose one method that will work on all the major Java IDEs. I'm just not sure which one it is. I'm currently leaning on the -source version, but I'd still like an "official" answer.

But what about PHP?

You might have noticed that PHP is a conspicuous absence from this MapGuide API enhancement work.

Well the truth is that PHP poses the following problems:
  • Besides constants.php there is no actual PHP source files to "compile" into. So there's no actual place to drop our translated doxygen comments into.
  • There is no officially defined standard for documenting PHP code. Even if there was, the real aim of this API enhancement work is to improve integrated API documentation (ie. From within an IDE). If all the PHP documentation solutions ultimately produce something similar to what we already have in our API reference (a web-based documentation source), then what is the real point? We already have that!
What's left?

Besides answering the Java IDE documentation question, this API enhancement will need a requisite test run on Linux (especially the SWIG/IMake stuff). All the viewers still work as before on Windows post-SWIG/IMake surgery, indicating the wrapper APIs haven't been negatively affected in any way.

Also I have to draft up an RFC for these enhancements, for eventual inclusion into the next major release of MapGuide Open Source (2.5). If everything pans out, this next release will have 4 Web API options:
  • PHP
  • .net (with XML documentation files for Visual Studio)
  • Java (the old crufty one, kept for compatibility purposes) with Java IDE documentation support (whatever it will be)
  • Java (the enhanced one with the changes described here) with Java IDE documentation support (whatever it will be)

Monday, 26 November 2012

Improving the MapGuide API documentation (part 2.5)

This is the latest result of some SWIG/IMake sandbox work. So far, so good!