<?xml version="1.0"?>

<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" 
          "http://forrest.apache.org/dtd/document-v20.dtd">

<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-->

<document> 

  <header> 
    <title>Writing user mapping connectors</title> 
  </header> 

  <body> 
    <section>
      <title>Writing a User Mapping Connector</title>
      <p></p>
      <p>A user mapping connector allows a user name to be transformed in a manner that depends on the functionality of the connector.  In some cases, no connection to
            an external repository is required (for example, simple string transformations), while in some cases one might imagine such a connector consulting with (say) an
            LDAP system to look up a specific name.</p>
      <p></p>
      <p>A user name is just a string, which is designed to represent a user identity.  Some user names have specific forms - for instance, Active Directory user names are
            often represented in the form <code>user@domain</code>.  But, most importantly, the exact name used can often depend on the particular system being addressed.</p>
      <p></p>
      <p>As is the case with all connectors under the ManifoldCF umbrella, a user mapping connector consists of a single part:</p>
      <p></p>
      <ul>
        <li>A class implementing an interface (in this case, <em>org.apache.manifoldcf.authorities.interfaces.IMappingConnector</em>)</li>
      </ul>
      <p></p>
      <section>
        <title>Key concepts</title>
        <p></p>
        <p>The mapping connector abstraction makes use of, or introduces, the following concepts:</p>
        <p></p>
        <table>
          <tr><th>Concept</th><th>What it is</th></tr>
          <tr><td>Configuration parameters</td><td>A hierarchical structure, internally represented as an XML document, which describes a specific configuration of a specific mapping connector, i.e. <strong>how</strong> the connector should do its job; see <em>org.apache.manifoldcf.core.interfaces.ConfigParams</em></td></tr>
          <tr><td>Mapping connection</td><td>An mapping connector instance that has been furnished with configuration data</td></tr>
          <tr><td>User name</td><td>The name of a user, which is often a Kerberos principal name, e.g. <em>john@apache.org</em></td></tr>
          <tr><td>Connection management/threading/pooling model</td><td>How an individual mapping connector class instance is managed and used</td></tr>
        </table>
        <p></p>
      </section>
      <section>
        <title>Implementing the Mapping Connector class</title>
        <p></p>
        <p>A very good place to start is to read the javadoc for the mapping connector interface.  You will note that the javadoc describes the usage and pooling model for a
              connector class pretty thoroughly.  It is very important to understand the model thoroughly in order to write reliable connectors!  Use of static variables, for one thing,
              must be done in a very careful way, to avoid issues that would be hard to detect with a cursory test.</p>
        <p></p>
        <p>The second thing to do is to examine some of the provided mapping connector implementations.  The only connector presently included (the Regular Expression
              user mapping connector) demonstrates some of the sorts of techniques you will need for an effective
              implementation.  You will also note that all of these connectors extend a framework-provided mapping connector base class, found at
              <em>org.apache.manifoldcf.authorities.mappers.BaseMappingConnector</em>.  This base class furnishes some basic bookkeeping logic for managing the
              connector pool, as well as default implementations of some of the less typical functionality a connector may have.  For example, connectors are allowed to have
              database tables of their own, which are instantiated when the connector is registered, and are torn down when the connector is removed.  This is, however, not
              very typical, and the base implementation reflects that.</p>
        <p></p>
        <section>
          <title>Principle methods</title>
          <p></p>
          <p>The principle methods an implementer should be concerned with for creating a mapping connector are the following:</p>
          <p></p>
          <table>
            <tr><th>Method</th><th>What it should do</th></tr>
            <tr><td><strong>mapUser()</strong></td><td>Given an input user name, find the corresponding output user name</td></tr>
            <tr><td><strong>outputConfigurationHeader()</strong></td><td>Output the head-section part of a mapping connection <em>ConfigParams</em> editing page</td></tr>
            <tr><td><strong>outputConfigurationBody()</strong></td><td>Output the body-section part of a mapping connection <em>ConfigParams</em> editing page</td></tr>
            <tr><td><strong>processConfigurationPost()</strong></td><td>Receive and process form data from a mapping connection <em>ConfigParams</em> editing page</td></tr>
            <tr><td><strong>viewConfiguration()</strong></td><td>Output the viewing HTML for a mapping connection <em>ConfigParams</em> object</td></tr>
          </table>
          <p></p>
          <p>These methods come in two broad classes: (a) functional methods for doing the work of the connector; (b) UI methods for configuring a connection.  Together they
                do the heavy lifting of your connector.</p>
          <p></p>
          <p></p>
        </section>
        <section>
          <title>Notes on connector UI methods</title>
          <p></p>
          <p>The crawler UI uses a tabbed layout structure, and thus each of these elements must properly implement the tabbed model.  This means that the "header" methods 
                above must add the desired tab names to a specified array, and the "body" methods must provide appropriate HTML which handles both the case where a tab is
                displayed, and where it is not displayed.  Also, it makes sense to use the appropriate css definitions, so that the connector UI pages have a similar look-and-feel
                to the rest of ManifoldCF's crawler ui.  We strongly suggest starting with one of the supplied mapping connector's UI code, both for a description of the arguments
                to each page, and for some decent ideas of ways to organize your connector's UI code.</p>
          <p></p>
        </section>
      </section>
      <section>
        <title>Implementation support provided by the framework</title>
        <p></p>
        <p>ManifoldCF's framework provides a number of helpful services designed to make the creation of a connector easier.  These services are summarized below.
              (This is not an exhaustive list, by any means.)</p>
        <p></p>
        <ul>
          <li>Lock management and synchronization (see <em>org.apache.manifoldcf.core.interfaces.LockManagerFactory</em>)</li>
          <li>Cache management (see <em>org.apache.manifoldcf.core.interfaces.CacheManagerFactory</em>)</li>
          <li>Local keystore management (see <em>org.apache.manifoldcf.core.KeystoreManagerFactory</em>)</li>
          <li>Database management (see <em>org.apache.manifoldcf.core.DBInterfaceFactory</em>)</li>
        </ul>
        <p></p>
        <p>For UI method support, these too are very useful:</p>
        <p></p>
        <ul>
          <li>Multipart form processing (see <em>org.apache.manifoldcf.ui.multipart.MultipartWrapper</em>)</li>
          <li>HTML encoding (see <em>org.apache.manifoldcf.ui.util.Encoder</em>)</li>
          <li>HTML formatting (see <em>org.apache.manifoldcf.ui.util.Formatter</em>)</li>
        </ul>
        <p></p>
      </section>
      <section>
        <title>DO's and DON'T DO's</title>
        <p></p>
        <p>It's always a good idea to make use of an existing infrastructure component, if it's meant for that purpose, rather than inventing your own.  There are, however,
              some limitations we recommend you adhere to.</p>
        <p></p>
        <ul>
          <li>DO make use of infrastructure components described in the section above</li>
          <li>DON'T make use of infrastructure components that aren't mentioned, without checking first</li>
          <li>NEVER write connector code that directly uses framework database tables, other than the ones installed and managed by your connector</li>
        </ul>
        <p></p>
        <p>If you are tempted to violate these rules, it may well mean you don't understand something important.  At the very least, we'd like to know why.  Send email
              to dev@manifoldcf.apache.org with a description of your problem and how you are tempted to solve it.</p>
      </section>
    </section>
  </body>
</document>