IAM Buckminster Integration

From Eclipsepedia

Revision as of 17:31, 29 September 2008 by Ismaeltf.gmail.com (Talk | contribs)

Jump to: navigation, search

< To: IAM

Contents

Introduction

When it's finished, Buckminster integration will allow IAM users to materialize Maven dependencies in their Eclipse workspace. That means that the user will be able to navigate through a Maven project's list of dependencies and to select what dependencies will be materialized in his/her workspace as Eclipse projects.

What is Buckminster

Buckminster is a component resolution and materialization framework presented as a plugin for Eclipse. For detailed information about this technology, please visit the Buckminster Project wiki.

IAM Buckminster integration features

  • Works with the Buckminster plug-in to materialize Maven dependencies. This allows us to rely on Buckminster's repository access and component materialization capabilities, being relatively easy for us to add support to new SCM systems in the future (as far as Buckminster supports them).
  • Right now, it allows the dependencies to be located in Subversion or CVS repositories, which should be enough for the most of users (at least we hope so).

User guide

To start materializing Maven dependencies you only need to follow this instructions:

  • Right click on a project managed by IAM (if a project has a pom.xml you can set it to be IAM-managed by right-clicking on it and toggling on the "Use Maven dependency management" option in the "Maven 2" sub-menu). Choose the "Materialize dependencies..." option in the "Maven 2" sub-menu.
  • A dialog will appear containing a list with those dependencies with a <scm> tag in their corresponding pom.xml's (more precisely, the <scm> tag must contain the <connection> tag for the dependency to be taken into account: obviously the plug-in needs to know where it must look for the dependency code ). Choose whatever dependencies you need to be materialized and click the OK button.


IAMBuckminster MaterializeDependenciesDialog.png


  • A CQUERY and a RMAP will be generated for each dependency (for details about CQUERYs and RMAPs please visit the Buckminster Project wiki) and Buckminster will try to materialize them. Be patient and, if nothing bad happens, the selected dependencies will appear as Eclipse projects in your workspace. (Right now, the feedback provided by the IAM Buckminster integration plug-in is almost non-existent, so if you need verbose information about what's happening during the materialization process you should go to the Eclipse preferences, then to the Buckminster section and set the console logger level as DEBUG).

Subversion

CVS

How it works

This section aims to explain the general idea behind the IAM Buckminster integration, but it's not necessary for the user to read it. Also, it's highly recommended to have some basic knowledge about the Buckminster plug-in to better understand the following.

An example

Let's consider a Maven project like log4j. Its SCM information (extracted from the log4j version 1.2.14 pom.xml) looks like this:

<scm>
  <connection>scm:svn:http://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_14</connection>
  <developerConnection>scm:svn:https://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_14</developerConnection>
  <url>http://svn.apache.org/viewcvs.cgi/logging/log4j/tags/v1_2_14/</url>
</scm>

Now, if log4j version 1.2.14 is one of the dependencies you choose to materialize, the IAM Buckminster integration plug-in will generate the following RMAP and CQUERY:

<rmap xmlns="http://www.eclipse.org/buckminster/RMap-1.0" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0" 
      xmlns:mp="http://www.eclipse.org/buckminster/MavenProvider-1.0">
  <searchPath name="log4j">
    <provider readerType="svn" componentTypes="unknown" source="true">
      <uri format="http://svn.apache.org/repos/asf/logging/log4j/trunk"/>
      <versionConverter type="tag" versionType="String">
        <transform fromPattern="^(.+)$" fromReplacement="$1" toPattern="^(.+)$" toReplacement="$1"/>
      </versionConverter>
    </provider>
    <provider readerType="svn" componentTypes="unknown" source="true">
      <uri format="http://svn.apache.org/repos/asf/logging/log4j/trunk"/>
      <versionConverter type="tag" versionType="String">
        <transform fromPattern="^(\d+)\.(\d+)$" fromReplacement="v$1_$2" 
                   toPattern="^v(\d+)_(\d+)$" toReplacement="$1\.$2"/>
        <transform fromPattern="^(\d+)\.(\d+)\.(\d+)$" fromReplacement="v$1_$2_$3" 
                   toPattern="^v(\d+)_(\d+)_(\d+)$" toReplacement="$1\.$2\.$3"/>
      </versionConverter>
    </provider>
    <provider readerType="svn" componentTypes="unknown" source="true">
      <uri format="http://svn.apache.org/repos/asf/logging/log4j/trunk"/>
      <versionConverter type="tag" versionType="String">
        <transform fromPattern="^(\d+)\.(\d+)$" fromReplacement="v_$1_$2" 
                   toPattern="^v_(\d+)_(\d+)$" toReplacement="$1\.$2"/>
        <transform fromPattern="^(\d+)\.(\d+)\.(\d+)$" fromReplacement="v_$1_$2_$3" 
                   toPattern="^v_(\d+)_(\d+)_(\d+)$" toReplacement="$1\.$2\.$3"/>
      </versionConverter>
    </provider>
    <provider readerType="svn" componentTypes="unknown" source="true">
      <uri format="http://svn.apache.org/repos/asf/logging/log4j/trunk"/>
      <versionConverter type="tag" versionType="String">
        <transform fromPattern="^(.*)$" fromReplacement="log4j_$1" toPattern="^log4j_(.*)$" toReplacement="$1"/>
        <transform fromPattern="^log4j_$" fromReplacement="log4j\." toPattern="^log4j\.$" toReplacement="log4j_"/>
        <transform fromPattern="\." fromReplacement="_" toPattern="_" toReplacement="\."/>
      </versionConverter>
    </provider>
    <provider readerType="svn" componentTypes="unknown" source="true">
      <uri format="http://svn.apache.org/repos/asf/logging/log4j/trunk"/>
      <versionConverter type="tag" versionType="String">
        <transform fromPattern="^(\d+)\.(\d+)$" fromReplacement="RELEASE-$1_$2" 
                   toPattern="^((?i)(RELEASE))-(\d+)_(\d+)$" toReplacement="$3\.$4"/>
        <transform fromPattern="^(\d+)\.(\d+)\.(\d+)$" fromReplacement="RELEASE-$1_$2_$3" 
                   toPattern="^((?i)(RELEASE))-(\d+)_(\d+)_(\d+)$" toReplacement="$3\.$4\.$5"/>
      </versionConverter>
    </provider>
  </searchPath>
  <locator searchPathRef="log4j" pattern="log4j"/>
</rmap>
<componentQuery xmlns:cq="http://www.eclipse.org/buckminster/CQuery-1.0"
                resourceMap="file:///home/superman/workspace/iam_rmap_log4j_999.rmap">
  <rootRequest name="log4j" componentType="unknown" versionDesignator="[v1_2_14,v1_2_14]" versionType="String"/>
</componentQuery>

With this two things (RMAP and CQUERY) we can now call Buckminster and ask it to materialize log4j into the user's workspace. We'll explain now some details about the generated CQUERY and RMAP:

  • The CQUERY (component query) has a pointer to the generated RMAP (we assume its location is /home/superman/workspace/iam_rmap_log4j_999.rmap) and requests the log4j component. There's some extra information: the component type is set to unknown because we don't need Buckminster to calculate log4j's dependencies; the version designator is [v1_2_14,v1_2_14] because we're looking for a certain version of log4j, and no other; and finally, the version type is String so we're taking the alphanumerical order to compare different versions.
  • Why is the version designator set to [v1_2_14,v1_2_14] and not to [1.2.14,1.2.14]? Even when the second seems more logical, we know in this case which tag corresponds to the dependency version (we inferred it from the <connection>scm:svn:http://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_14</connection> tag) so we can ask Buckminster to look for the code contained in the Subversion repository tag v_1_2_14 instead of relying in the transformations we'll talk about later (which are described in the RMAP). By the way, we know the SCM system used by the log4j project is Subversion because of the scm:svn fragment of the connection tag.
  • The RMAP describes one search path which corresponds with the log4j component. This search path points to http://svn.apache.org/repos/asf/logging/log4j/trunk, a URL which was obtained from the http://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_14 URL in the connection tag. Buckminster only recognizes Subversion connections to the trunk path, so this transformation must be performed. But the first URL contains a tags directory, so we're looking for a tag, not for the trunk. This must be configured in the RMAP with the help of the version converters. Apart from telling Buckminster that we want a tag, version converters can describe version transformations.
  • What are transformations good for? If the IAM Buckminster integration plug-in cannot infer which tag inhabits the component we want, it tries to find it transforming its version. For example, we're looking for the version 1.2.14 of log4j, and if we didn't know it is located in the v1_2_14 tag, we'd try to find it in the v_1_2_14, log4j-1_2_14, release-1_2_14, ... tags. These are some of the transformations defined in the RMAP (there's also a transformation which doesn't change anything which works when we know exactly where tag to look in). Transformations are specially important if we're working with CVS (we never can infer the exact tag where a component is located when we use CVS because the connection strings are like this: scm:cvs:pserver:anonymous@cvs.sourceforge.net:/cvsroot/easyconf:easyconf).
  • By the way, if we were looking for the trunk of log4j and not for a tag, the generated RMAP would be as simple as this:
<rmap xmlns="http://www.eclipse.org/buckminster/RMap-1.0" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:bc="http://www.eclipse.org/buckminster/Common-1.0" 
      xmlns:mp="http://www.eclipse.org/buckminster/MavenProvider-1.0">
  <searchPath name="log4j">
    <provider readerType="svn" componentTypes="unknown" source="true">
      <uri format="http://svn.apache.org/repos/asf/logging/log4j/trunk"/>
    </provider>
  </searchPath>
  <locator searchPathRef="log4j" pattern="log4j"/>
</rmap>