<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ ModeShape (http://www.modeshape.org)
  ~
  ~ See the COPYRIGHT.txt file distributed with this work for information
  ~ regarding copyright ownership.  Some portions may be licensed
  ~ to Red Hat, Inc. under one or more contributor license agreements.
  ~ See the AUTHORS.txt file in the distribution for a full listing of 
  ~ individual contributors.
  ~
  ~ ModeShape is free software. Unless otherwise indicated, all code in ModeShape
  ~ is licensed to you under the terms of the GNU Lesser General Public License as
  ~ published by the Free Software Foundation; either version 2.1 of
  ~ the License, or (at your option) any later version.
  ~
  ~ ModeShape is distributed in the hope that it will be useful,
  ~ but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  ~ or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
  ~ for more details.
  ~
  ~ You should have received a copy of the GNU Lesser General Public License
  ~ along with this distribution; if not, write to:
  ~ Free Software Foundation, Inc.
  ~ 51 Franklin Street, Fifth Floor
  ~ Boston, MA  02110-1301  USA
  -->
<!DOCTYPE preface PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"	[
<!ENTITY % CustomDTD SYSTEM "../../custom.dtd">
%CustomDTD;
]>
<chapter id="execution_context">
  <title>Execution Context</title>
  <para>
		The various components of ModeShape are designed as plain old Java objects, or POJOs (Plain Old Java Objects).  And rather than making assumptions
		about their environment, each component instead requires that any external dependencies necessary for it to operate
		must be supplied to it.  This pattern is known as Dependency Injection, and it allows the components to be simpler
		and allows for a great deal of flexibility and customization in how the components are configured.  
  </para>
	<para>
		The approach that ModeShape takes is simple: a simple POJO that represents everything about the environment
		in which components operate.  Called &ExecutionContext;, it contains references to most of the essential
		facilities, including: security (authentication and authorization); namespace registry; name factories; factories 
		for properties and property values; logging; and access to class loaders (given a classpath).  
		Most of the ModeShape components require an &ExecutionContext; and thus have access to all these facilities.
	</para>
	<para>
		The &ExecutionContext; is a concrete class that is instantiated with the no-argument constructor:
	</para>
	<programlisting>
public class &ExecutionContext; implements &ClassLoaderFactory; {

    /**
     * Create an instance of an execution context, with default implementations for all components.
     */
    public &ExecutionContext;() { ... }

    /**
     * Get the factories that should be used to create values for {@link Property properties}.
     * @return the property value factory; never null
     */
    public &ValueFactories; getValueFactories() {...}

    /**
     * Get the namespace registry for this context.
     * @return the namespace registry; never null
     */
    public &NamespaceRegistry; getNamespaceRegistry() {...}

    /**
     * Get the factory for creating {@link Property} objects.
     * @return the property factory; never null
     */
    public &PropertyFactory; getPropertyFactory() {...}

    /**
     * Get the security context for this environment.
     * @return the security context; never <code>null</code>
     */
    public &SecurityContext; getSecurityContext() {...}

    /**
     * Return a logger associated with this context. This logger records only those activities within the 
     * context and provide a way to capture the context-specific activities. All log messages are also
     * sent to the system logger, so classes that log via this mechanism should <i>not</i> also 
     * {@link Logger#getLogger(Class) obtain a system logger}.
     * @param clazz the class that is doing the logging
     * @return the logger, named after <code>clazz</code>; never null
     */
    public &Logger; getLogger( Class&lt;?> clazz ) {...}

    /**
    * Return a logger associated with this context. This logger records only those activities within the 
    * context and provide a way to capture the context-specific activities. All log messages are also
    * sent to the system logger, so classes that log via this mechanism should <i>not</i> also 
    * {@link Logger#getLogger(Class) obtain a system logger}.
     * @param name the name for the logger
     * @return the logger, named after <code>clazz</code>; never null
     */
    public &Logger; getLogger( String name ) {...}

		...
}
</programlisting>
  <para>
		The fact that so many of the ModeShape components take &ExecutionContext; instances gives us some interesting possibilities.  
		For example, one execution context instance can be used as the highest-level (or "application-level") context for all of the services 
		(e.g., &RepositoryService;, &SequencingService;, etc.).
		Then, an execution context could be created for each user that will be performing operations, and that user's context can
		be passed around to not only provide security information about the user but also to allow the activities being performed
		to be recorded for user feedback, monitoring and/or auditing purposes.
	</para>
	<para>
		As mentioned above, the starting point is to create a default execution context, which will have all the default components:
	</para>
<programlisting>
&ExecutionContext; context = new &ExecutionContext;();
</programlisting>
	<para>
		Once you have this top-level context, you can start creating <emphasis>subcontexts</emphasis> with different components,
		and different security contexts.  (Of course, you can create a subcontext from any &ExceutionContext; instance.)
		To create a subcontext, simply use one of the <code>with(...)</code> methods on the parent context.  We'll show examples
		later on in this chapter.
	</para>
	<sect1 id="security">
		<title>Security</title>
	  <para>
	    ModeShape uses a simple abstraction layer to isolate it from the security infrastructure used within an application.
	    A &SecurityContext; represents the context of an authenticated user, and is defined as an interface:
		</para>
	  <programlisting>
public interface &SecurityContext; {

    /**
     * Get the name of the authenticated user.
     * @return the authenticated user's name
     */
    String getUserName();

    /**
     * Determine whether the authenticated user has the given role.
     * @param roleName the name of the role to check
     * @return true if the user has the role and is logged in; false otherwise
     */
    boolean hasRole( String roleName );

    /**
     * Logs the user out of the authentication mechanism.
     * For some authentication mechanisms, this will be implemented as a no-op.
     */
    void logout();
}
</programlisting>
		<para>
			Every &ExecutionContext; has a &SecurityContext; instance, though the top-level (default) execution context does not represent
			an authenticated user.  But you can create a subcontext for a user authenticated via JAAS:
		</para>
<programlisting>
&ExecutionContext; context = ...
String username = ...
char[] password = ...
String jaasRealm = ...
&SecurityContext; securityContext = new JaasSecurityContext(jaasRealm, username, password);
&ExecutionContext; userContext = context.with(securityContext);
</programlisting>
		<para>
			In the case of JAAS, you might not have the password but would rather prompt the user.  In that case, simply create
			a subcontext with a different security context:
		</para>
<programlisting>
&ExecutionContext; context = ...
String jaasRealm = ...
&CallbackHandler; callbackHandler = ...
&ExecutionContext; userContext = context.with(new JaasSecurityContext(jaasRealm, callbackHandler);
</programlisting>
		<para>
			Of course if your application has a non-JAAS authentication and authorization system, you can simply provide your own implementation
			of &SecurityContext;:
		</para>
<programlisting>
&ExecutionContext; context = ...
&SecurityContext; mySecurityContext = ...
&ExecutionContext; myAppContext = context.with(mySecurityContext);
</programlisting>
		<para>
			These &ExecutionContext;s then represent the authenticated user in any component that uses the context.
		</para>
		<sect2 id="jaas_security">
			<title>JAAS</title>
			<para>
				One of the &SecurityContext; implementations provided by ModeShape is the &JaasSecurityContext;, which delegates any authentication 
				or authorization requests to a <ulink url="http://java.sun.com/javase/technologies/security/">Java Authentication and Authorization Service (JAAS)</ulink>
		    provider.  This is the standard approach for authenticating and authorizing in Java.  
		  </para>
		  <para>
				There are quite a few JAAS providers available, but one of the best and most powerful providers is
		    <ulink url="http://www.jboss.org/jbosssecurity/">JBoss Security</ulink>, the open source
				security framework used by JBoss.  JBoss Security offers a number of JAAS login modules, including:
		    <itemizedlist>
		      <listitem>
		        <para>
		          <emphasis role="strong">User-Roles Login Module</emphasis>
		          is a simple
		          <code>javax.security.auth.login.LoginContext</code>
		          implementation that uses usernames and passwords stored in a properties file.
		        </para>
		      </listitem>
		      <listitem>
		        <para>
		          <emphasis role="strong">Client Login Module</emphasis>
		          prompts the user for their username and password.
		        </para>
		      </listitem>
		      <listitem>
		        <para>
		          <emphasis role="strong">Database Server Login Module</emphasis>
		          uses a JDBC database to authenticate principals and associate them with roles.
		        </para>
		      </listitem>
		      <listitem>
		        <para>
		          <emphasis role="strong">LDAP Login Module</emphasis>
		          uses an LDAP directory to authenticate principals. Two implementations are available.
		        </para>
		      </listitem>
		      <listitem>
		        <para>
		          <emphasis role="strong">Certificate Login Module</emphasis>
		          authenticates using X509 certificates, obtaining roles from either property files or a JDBC database.
		        </para>
		      </listitem>
		      <listitem>
		        <para>
		          <emphasis role="strong">Operating System Login Module</emphasis>
		          authenticates using the operating system's mechanism.
		        </para>
		      </listitem>
		    </itemizedlist>
		    and many others.  Plus, JBoss Security also provides other capabilities, such as using XACML policies or using federated single sign-on. 
				For more detail, see the <ulink url="http://www.jboss.org/jbosssecurity/">JBoss Security</ulink> project.
		  </para>

            <sect3 id="user_roles_configuration">
                <title>User-Roles Configuration</title>
                <para>
                    When assigning users to roles via properties files (e.g. when using the User-Roles Login Module), each line
                    contains the comma-separated list of roles for a particular user, and is of the form:
                </para>
                <programlisting>&lt;username&gt;=&lt;role&gt;[,&lt;role&gt;,...] where:</programlisting>

                <itemizedlist>
                    <listitem>
                        <para>
                            <emphasis role="strong">&lt;username&gt;</emphasis> is the name of the user
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <emphasis role="strong">&lt;role&gt;</emphasis> is an expression describing a role for the user and
                            which adheres to the format
                        </para>
                    </listitem>
                </itemizedlist>

                <programlisting>&lt;role&gt;=&lt;roleName&gt;[.&lt;sourceName&gt;[.&lt;workspaceName&gt;]] where:</programlisting>

                <itemizedlist>
                    <listitem>
                        <para>
                            <emphasis role="strong">&lt;roleName&gt;</emphasis>
                            is one of "admin", "readonly", "readwrite", or (for WebDAV and RESTful access) "connect"
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <emphasis role="strong">&lt;sourceName&gt;</emphasis>, is the name of the repository source to which
                            the role is granted; if absent, the role will be granted for all repository sources
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            <emphasis role="strong">&lt;workspaceName&gt;</emphasis>, is the name of the repository workspace to
                            which the role is granted; if absent, the role will be granted for all workspaces in the repository
                        </para>
                    </listitem>
                </itemizedlist>

                <para>
                    For example, the following line provides all roles to user 'jsmith' for all workspaces in all repositories:
                    <emphasis role="strong">jsmith=admin,connect,readonly,readwrite</emphasis> while <emphasis role="strong">jsmith=connect,readonly,readwrite.customers</emphasis>
                    provides connect and read access to all repositories, but only write access to all workspaces in the 'customers' repository
                </para>
                <para>
                    When using the JBoss AS kit, the properties file handling these assignments is: <emphasis role="strong">modeshape-roles.properties</emphasis>
                </para>
            </sect3>
		</sect2>
		<sect2 id="web_security">
			<title>Web application security</title>
			<para>
				If ModeShape is being used within a web application, then it is probably desirable to reuse the security infrastructure
				of the application server.  This can be accomplished by implementing the &SecurityContext; interface with an implementation
				that delegates to the <interface>HttpServletRequest</interface>.  Then, for each request, create a &SecurityContextCredentials;
				instance around your &SecurityContext;, and use that credentials to obtain a JCR &Session;.
			</para>
			<para>
				Here is an example of the &SecurityContext; implementation that uses the servlet request:
			</para>
	  <programlisting>
@Immutable
public class ServletSecurityContext implements &SecurityContext; {

    private final String userName;
    private final HttpServletRequest request;

    /**
     * Create a {@link ServletSecurityContext} with the supplied 
     * {@link HttpServletRequest servlet information}.
     * 
     * @param request the servlet request; may not be null
     */
    public ServletSecurityContext( HttpServletRequest request ) {
        this.request = request;
        this.userName = request.getUserPrincipal() != null ? request.getUserPrincipal().getName() : null;
    }

    /**
     * Get the name of the authenticated user.
     * @return the authenticated user's name
     */
    public String getUserName() {
        return userName;
    }

    /**
     * Determine whether the authenticated user has the given role.
     * @param roleName the name of the role to check
     * @return true if the user has the role and is logged in; false otherwise
     */
    boolean hasRole( String roleName ) {
        request.isUserInRole(roleName);
    }

    /**
     * Logs the user out of the authentication mechanism.
     * For some authentication mechanisms, this will be implemented as a no-op.
     */
    public void logout() {
    }
}</programlisting>
			<para>
				Then use this to create a &Session;:
			</para>
<programlisting>
HttpServletRequest request = ...
&Repository; repository = engine.getRepository("my repository");
&SecurityContext; securityContext = new ServletSecurityContext(httpServletRequest);
&ExecutionContext; servletContext = context.with(securityContext);
</programlisting>
			<para>
				We'll see later in the <link linkend="jcr">JCR chapter</link> how this can be used to obtain a JCR &Session; for
				the authenticated user.
			</para>
		</sect2>
	</sect1>
	<sect1 id="namespace_registry">
		<title>Namespace Registry</title>
	  <para>
	    As we saw earlier, every &ExecutionContext; has a registry of namespaces.  Namespaces are used throughout the graph API
	    (as we'll see soon), and the prefix associated with each namespace makes for more readable string representations.
	    The namespace registry tracks all of these namespaces and prefixes, and allows registrations to be added, modified, or
		  removed.  The interface for the &NamespaceRegistry; shows how these operations are done:
		</para>
	  <programlisting>
public interface &NamespaceRegistry; {

    /**
     * Return the namespace URI that is currently mapped to the empty prefix.
     * @return the namespace URI that represents the default namespace, 
     * or null if there is no default namespace
     */
    String getDefaultNamespaceUri();

    /**
     * Get the namespace URI for the supplied prefix.
     * @param prefix the namespace prefix
     * @return the namespace URI for the supplied prefix, or null if there is no 
     * namespace currently registered to use that prefix
     * @throws IllegalArgumentException if the prefix is null
     */
    String getNamespaceForPrefix( String prefix );

    /**
     * Return the prefix used for the supplied namespace URI.
     * @param namespaceUri the namespace URI
     * @param generateIfMissing true if the namespace URI has not already been registered and the 
     *        method should auto-register the namespace with a generated prefix, or false if the  
     *        method should never auto-register the namespace
     * @return the prefix currently being used for the namespace, or "null" if the namespace has 
     *         not been registered and "generateIfMissing" is "false"
     * @throws IllegalArgumentException if the namespace URI is null
     * @see #isRegisteredNamespaceUri(String)
     */
    String getPrefixForNamespaceUri( String namespaceUri, boolean generateIfMissing );

    /**
     * Return whether there is a registered prefix for the supplied namespace URI.
     * @param namespaceUri the namespace URI
     * @return true if the supplied namespace has been registered with a prefix, or false otherwise
     * @throws IllegalArgumentException if the namespace URI is null
     */
    boolean isRegisteredNamespaceUri( String namespaceUri );

    /**
     * Register a new namespace using the supplied prefix, returning the namespace URI previously 
     * registered under that prefix.
     * @param prefix the prefix for the namespace, or null if a namesapce prefix should be generated 
     *        automatically
     * @param namespaceUri the namespace URI
     * @return the namespace URI that was previously registered with the supplied prefix, or null if the 
     *         prefix was not previously bound to a namespace URI
     * @throws IllegalArgumentException if the namespace URI is null
     */
    String register( String prefix, String namespaceUri );

    /**
     * Unregister the namespace with the supplied URI.
     * @param namespaceUri the namespace URI
     * @return true if the namespace was removed, or false if the namespace was not registered
     * @throws IllegalArgumentException if the namespace URI is null
     * @throws NamespaceException if there is a problem unregistering the namespace
     */
    boolean unregister( String namespaceUri );

    /**
     * Obtain the set of namespaces that are registered.
     * @return the set of namespace URIs; never null
     */
    Set&lt;String> getRegisteredNamespaceUris();

    /**
     * Obtain a snapshot of all of the {@link Namespace namespaces} registered at the time this method 
     * is called. The resulting set is immutable, and will not reflect changes made to the registry.
     * @return an immutable set of &Namespace; objects reflecting a snapshot of the registry; never null
     */
    Set&lt;&Namespace;> getNamespaces();
}
</programlisting>
		<para>
			This interfaces exposes &Namespace; objects that are immutable:
		</para>
<programlisting>
@Immutable
interface &Namespace; extends Comparable&lt;&Namespace;> {
    /**
     * Get the prefix for the namespace
     * @return the prefix; never null but possibly the empty string
     */
    String getPrefix();

    /**
     * Get the URI for the namespace
     * @return the namespace URI; never null but possibly the empty string
     */
    String getNamespaceUri();
}
</programlisting>
			<para>
				ModeShape actually uses several implementations of &NamespaceRegistry;, but you can even implement your own
				and create &ExecutionContext;s that use it:
			</para>
<programlisting>
&NamespaceRegistry; myRegistry = ...
&ExecutionContext; contextWithMyRegistry = context.with(myRegistry);
</programlisting>
	</sect1>
	<sect1 id="class_loader_factory">
		<title>Class Loaders</title>
	  <para>
	  	ModeShape is designed around extensions: sequencers, connectors, MIME type detectors, and class loader factories.
			The core part of ModeShape is relatively small and has few dependencies, while many of the "interesting" components
			are extensions that plug into and are used by different parts of the core or by layers above (such as the
			<link linkend="jcr">JCR implementation</link>).  The core doesn't really care what
			the extensions do or what external libraries they require, as long as the extension fulfills its end of the
			extension contract.
		</para>
		<para>
			This means that you only need the core modules of ModeShape on the application classpath, while the extensions
			do not have to be on the application classpath.  And because the core modules of ModeShape have few dependencies,
			the risk of ModeShape libraries conflicting with the application's are lower.  Extensions, on the other hand,
			will likely have a lot of unique dependencies. By separating the core of ModeShape from the class loaders used
			to load the extensions, your application is isolated from the extensions and their dependencies. 
		</para>
		<note>
			<para>Of course, you can put all the JARs on the application classpath, too. 
				This is what the examples in the &GettingStarted; document do.
			</para>
		</note>
		<para>
			But in this case, how does ModeShape load all the extension classes?  You may have noticed earlier that 
			&ExecutionContext; implements	the &ClassLoaderFactory; interface with a single method:
		</para>
		<programlisting>
public interface &ClassLoaderFactory; {
    /**
     * Get a class loader given the supplied classpath.  The meaning of the classpath 
     * is implementation-dependent.
     * @param classpath the classpath to use
     * @return the class loader; may not be null
     */
    &ClassLoader; getClassLoader( &String;... classpath );
}
</programlisting>
		<para>
			This means that any component that has a reference to an &ExecutionContext; has the ability to create a
			class loader with a supplied class path.  As we'll see later, the connectors and sequencers are all
			defined with a class and optional class path.  This is where that class path comes in.
		</para>
		<para>
			The actual meaning of the class path, however, is a function of the implementation.  ModeShape uses
			a &StandardClassLoaderFactory; that just loads the classes using the Thread's current context
			class loader (or, if there is none, delegates to the class loader that loaded the &StandardClassLoaderFactory; class).
			Of course, it's possible to implement other &ClassLoaderFactory; with other implementations.
			Then, just create a subcontext with your implementation:
		</para>
<programlisting>
&ClassLoaderFactory; myClassLoaderFactory = ...
&ExecutionContext; contextWithMyClassLoaderFactories = context.with(myClassLoaderFactory);
</programlisting>
		<note>
	    <para>
	    	The <code>modeshape-classloader-maven</code> project has a class loader factory implementation that parses the names into
				<ulink url="http://maven.apache.org/pom.html#Maven_Coordinates">Maven coordinates</ulink>, then uses those coordinates
				to look up artifacts in a Maven 2 repository.  The artifact's POM file is used to determine the dependencies,
				which is done transitively to obtain the complete dependency graph.  The resulting class loader has access
				to these artifacts in dependency order.
			</para>
			<para>
				This class loader is not ready for use, however, since there is no tooling to help populate the repository.
			</para>
	  </note>
	</sect1>
	<sect1 id="mime-type-detectors">
		<title>MIME Type Detectors</title>
	  <para>
	  	ModeShape often needs the ability to determine the MIME type for some binary content.  When uploading content into
			a repository, we may want to add the MIME type as metadata.  Or, we may want to make some processing decisions
			based upon the MIME type.  So, ModeShape has a small pluggable framework for determining the MIME type by using
			the name of the file (e.g., extensions) and/or by reading the actual content.
	  </para>
    <para>
	 		ModeShape defines a &MimeTypeDetector; interface that abstracts the implementation that actually determines
			the MIME type given the name and content.
			If the detector is able to determine the MIME type, it simply returns
			it as a string.  If not, it merely returns null.  Note, however, that a detector must be thread-safe.
			Here is the interface:
		</para>
		<programlisting>
@ThreadSafe
public interface &MimeTypeDetector; {

    /**
     * Returns the MIME-type of a data source, using its supplied content and/or its supplied name, 
     * depending upon the implementation. If the MIME-type cannot be determined, either a "default" 
     * MIME-type or <code>null</code> may be returned, where the former will prevent earlier 
     * registered MIME-type detectors from being consulted.
     * 
     * @param name The name of the data source; may be <code>null</code>.
     * @param content The content of the data source; may be <code>null</code>.
     * @return The MIME-type of the data source, or optionally <code>null</code> 
     * if the MIME-type could not be determined.
     * @throws &IOException; If an error occurs reading the supplied content.
     */
    &String; mimeTypeOf( &String; name, &InputStream; content ) throws &IOException;;
}</programlisting>
		<para>
			To use a detector, simply invoke the method and supply the name of the content (e.g., the name of the file, with the extension)
			and the &InputStream; to the actual binary content.  The result is a &String; containing the 
			<ulink url="http://www.iana.org/assignments/media-types/">MIME type</ulink>
		  (e.g., "text/plain") or null if the MIME type cannot be determined.  Note that the name or &InputStream; may be
			null, making this a very versatile utility.
		</para>
		<para>
			Once again, you can obtain a &MimeTypeDetector; from the &ExecutionContext;.  ModeShape provides and uses by
			default an implementation that uses only the name (the content is ignored), looking at the name's extension
			and looking for a match in a small listing (loaded from the <code>org/modeshape/graph/mime.types</code> loaded from the classpath).
			You can add extensions by copying this file, adding or correcting the entries, and then placing your updated file in the
			expected location on the classpath.
		</para>
		<para>
			Of course, you can always use a different &MimeTypeDetector; by creating a subcontext and supplying your implementation:
		</para>
<programlisting>
&MimeTypeDetector; myDetector = ...
&ExecutionContext; contextWithMyDetector = context.with(myDetector);
</programlisting>
	</sect1>
	<sect1 id="text-extractors">
		<title>Text Extractors</title>
	  <para>
	  	ModeShape can store all kinds of content, and ModeShape makes it easy to perform full-text searches on that content.
	    To support searching, ModeShape extracts the text from the various properties on each node. They way it does this for
	    most property types (e.g., STRING, LONG, DATE, PATH, NAME, etc.) is simply to read and use the literal values.
	  	But BINARY properties are another story: there's no way to indexes the binary content directly. Instead, ModeShape
	 		has a small pluggable framework for extracting useful text from the binary content, based upon the MIME type of
			the content itself.
		</para>
		<para>
			The process works like this: when a BINARY property needs to be indexed for search, ModeShape determines the MIME
			type of the content, determines if there is a text extractor capable of handling that MIME type, and if so it
			passes the content to the text extractor and gets back a string of text, and it indexes that text.
		</para>
		<para>
			ModeShape provides two text extractors out-of-the-box. The Teiid VDB text extractor operates only upon
			Teiid virtual database (i.e., ".vdb") files and extracts the virtual database's logical name, description, and 
			version, plus the logical name, description, source	name, source translator name, and JNDI name for each of the 
			virtual database's models.
		</para>
		<para>
			The second out-of-the-box extractor is capable of extracting text from wider variety of file types, including
			Microsoft Office, PDF, HTML, plain text, and XML. This extractor uses the
			<ulink url="http://tika.apache.org/">Tika</ulink> toolkit from Apache, so a number of other file formats are
			supported. However, these other file formats require additional libraries that are not included out of the box.
			This is discussed in more detail in a <link linkend="tika-text-extractor">later chapter</link>.
		</para>
		<para>
			Text extraction can be an intensive process, so it is not enabled by default. But enabling the text extractors
			in ModeShape's configuration is actually pretty easy. When using a configuration file, simply add a "&lt;mode:textExtractors>"
			fragment under the "&lt;configuration>" root element. Within the "&lt;mode:textExtractors>" element place one or more 
			"&lt;mode:textExtractor>" fragments specifying at least the extractor's name and fully-qualified Java class.
		</para>
		<para>
			For example, here is the fragment that defines the Teiid text extractor and the Tika text extractor.
			Note that the Teiid text extractor has no options and is pretty simple, while the Tika extractor allows
			much more control over the MIME types that should be processed:
		</para>
		<programlisting language="XML" role="XML"><![CDATA[
<mode:textExtractors>
    <mode:textExtractor jcr:name="VDB Text Extractors">
      <mode:description>Extract text from Teiid VDB files</mode:description>        
      <mode:classname>org.modeshape.extractor.teiid.TeiidVdbTextExtractor</mode:classname>
    </mode:textExtractor>

    <mode:textExtractor jcr:name="Tika Text Extractors">
      <mode:description>Text extractors using Tika parsers</mode:description>        
      <mode:classname>org.modeshape.extractor.tika.TikaTextExtractor</mode:classname>
      <!-- 
      A comma- or whitespace-delimited list of MIME types that are to be excluded. 
      The following are excluded by default, but the default is completely overridden 
      when this property is set. In other words, if you explicitly exclude any MIME types,
      be sure to list all of the MIME types you want to exclude. Exclusions always 
      have a higher precedence than inclusions.
      -->
      <mode:excludedMimeTypes>
         application/x-archive,application/x-bzip,application/x-bzip2, 
         application/x-cpio,application/x-gtar,application/x-gzip, 
         application/x-ta,application/zip,application/vnd.teiid.vdb
      </mode:excludedMimeTypes>
      <!-- 
      A comma- or whitespace-delimited list of MIME types that are to be included. 
      If this is used, then the extractor will include only those MIME types found 
      in this list for which there is an available parser (unless the MIME type
      is also excluded). Including explicit MIME types is often easier if text is 
      to be extracted for are only a few MIME types.
      -->
      <mode:includedMimeTypes>
         application/msword,application/vnd.oasis.opendocument.text
      </mode:includedMimeTypes>
    </mode:textExtractor>
    ... <!-- other extractors -->
  </mode:textExtractors>
]]></programlisting>
    <para>
			It's also possible to define your own text extractors by implementing the &TextExtractor; interface:
		</para>
		<programlisting>
@ThreadSafe
public interface &TextExtractor; {

    /**
     * Determine if this extractor is capable of processing content with the supplied MIME type.
     * 
     * @param mimeType the MIME type; never null
     * @return true if this extractor can process content with the supplied MIME type, or false otherwise.
     */
    boolean supportsMimeType( &String; mimeType );

    /**
     * Sequence the data found in the supplied stream, placing the output information into the supplied map.
     * <p>
     * ModeShape's SequencingService determines the sequencers that should be executed by monitoring the changes to one or more
     * workspaces that it is monitoring. Changes in those workspaces are aggregated and used to determine which sequencers should
     * be called. If the sequencer implements this interface, then this method is called with the property that is to be sequenced
     * along with the interface used to register the output. The framework takes care of all the rest.
     * </p>
     * 
     * @param stream the stream with the data to be sequenced; never <code>null</code>
     * @param output the output from the sequencing operation; never <code>null</code>
     * @param context the context for the sequencing operation; never <code>null</code>
     * @throws IOException if there is a problem reading the stream
     */
    void extractFrom( &InputStream; stream,
                      &TextExtractorOutput; output,
                      &TextExtractorContext; context ) throws IOException;

}</programlisting>
		<para>
			As mentioned above, the "supportsMimeType" method will be called first, and only if your implementation
			returns true for a given MIME type will the "extractFrom" method be called. The supplied &TextExtractorContext;
			object provides information about the text being processed, while the &TextExtractorOutput; is a simple
			interface that your extractor uses to record one or more strings containing the extracted text.
		</para>
		<para>
			If you need text extraction in sequencers or connectors, you can always get a &TextExtractor; instance
			from the &ExecutionContext;. That &TextExtractor; implementation is actually a composite of all of the
			text extractors defined in the configuration.
		</para>
		<para>
			Of course, you can always use a different &TextExtractor; by creating a subcontext and supplying your implementation:
		</para>
<programlisting>
&TextExtractor; myExtractor = ...
&ExecutionContext; contextWithMyExtractor = context.with(myExtractor);
</programlisting>
	</sect1>
	<sect1>
		<title>Property factory and value factories</title>
		<para>
			Two other components are made available by the &ExecutionContext;.  The &PropertyFactory; is an interface
			that can be used to create &Property; instances, which are used throughout the graph API.  The &ValueFactories;
			interface provides access to a number of different factories for different kinds of property values.
			These will be discussed in much more detail in the next chapter.  But like the other components that
			are in an &ExecutionContext;, you can create subcontexts with different implementations:
		</para>
<programlisting>
&PropertyFactory; myPropertyFactory = ...
&ExecutionContext; contextWithMyPropertyFactory = context.with(myPropertyFactory);
</programlisting>
		<para>and</para>
<programlisting>
&ValueFactories; myValueFactories = ...
&ExecutionContext; contextWithMyValueFactories = context.with(myValueFactories);
</programlisting>
		<para>
			Of course, implementing your own factories is a pretty advanced topic, and it will likely be something you do not
			need to do in your application.
		</para>
	</sect1>
	<sect1>
		<title>Summary</title>
		<para>
			In this chapter, we introduced the &ExecutionContext; as a representation of the environment in which many of the
			ModeShape components operate.  &ExecutionContext; provides a very simple but powerful way to inject commonly-needed
			facilities throughout the system.
		</para>
		<para>
			In the <link linkend="graph-model">next chapter</link>, we'll dive into Graph API and will introduce the notion of
			nodes, paths, names, and properties, that are so essential and used throughout ModeShape.
		</para>
	</sect1>
</chapter>

