org.apache.jackrabbit.commons
Class JcrUtils

java.lang.Object
  extended by org.apache.jackrabbit.commons.JcrUtils

public class JcrUtils
extends Object

Collection of static utility methods for use with the JCR API.

Since:
Apache Jackrabbit 2.0

Field Summary
static Value[] NO_VALUES
          A pre-allocated empty array of values.
static String REPOSITORY_URI
          The repository URI parameter name used by the getRepository(String) method.
 
Method Summary
static Iterable<Node> getChildNodes(Node node)
          Calls Node.getNodes() on the given node and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.
static Iterable<Node> getChildNodes(Node node, String pattern)
          Calls Node.getNodes(String) on the given node with the given name pattern and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.
static Iterable<Node> getChildNodes(Node node, String[] globs)
          Calls Node.getNodes(String[]) on the given node with the given name globs and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.
 Calendar getLastModified(Node node)
          Returns the last modified date of the given file node.
static Iterable<Node> getNodes(QueryResult result)
          Calls QueryResult.getNodes() on the given query result and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.
static Node getOrAddFolder(Node parent, String name)
          Returns the named child of the given node, creating it as an nt:folder node if it does not already exist.
static Node getOrAddNode(Node parent, String name)
          Returns the named child of the given node, creating the child if it does not already exist.
static Node getOrAddNode(Node parent, String name, String type)
          Returns the named child of the given node, creating the child if it does not already exist.
static Node getOrCreateByPath(Node baseNode, String path, boolean createUniqueLeaf, String intermediateNodeType, String nodeType, boolean autoSave)
          Creates or gets the Node at the given path relative to the baseNode.
static Node getOrCreateByPath(String absolutePath, boolean createUniqueLeaf, String intermediateNodeType, String nodeType, Session session, boolean autoSave)
          Creates or gets the Node at the given Path.
static Node getOrCreateByPath(String absolutePath, String nodeType, Session session)
          Creates or gets the Node at the given Path.
static Node getOrCreateByPath(String absolutePath, String intermediateNodeType, String nodeType, Session session, boolean autoSave)
          Creates or gets the Node at the given Path.
static Node getOrCreateUniqueByPath(Node parent, String nodeNameHint, String nodeType)
          Creates or gets the Node at the given Path.
static Node getOrCreateUniqueByPath(String pathHint, String nodeType, Session session)
          Creates a Node at the given Path.
static Iterable<Property> getProperties(Node node)
          Calls Node.getProperties() on the given node and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.
static Iterable<Property> getProperties(Node node, String pattern)
          Calls Node.getProperties(String) on the given node with the given name pattern and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.
static Iterable<Property> getProperties(Node node, String[] globs)
          Calls Node.getProperties(String[]) on the given node with the given name globs and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.
static int getPropertyType(String name)
          Returns the numeric constant value of the property type with the specified name.
static Iterable<Property> getReferences(Node node)
          Calls Node.getReferences() on the given node and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.
static Iterable<Property> getReferences(Node node, String name)
          Calls Node.getReferences(String) on the given node and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.
static Repository getRepository()
          Returns the default repository of the current environment.
static Repository getRepository(Map<String,String> parameters)
          Looks up the available repository factories and returns the repository that one of the factories returns for the given settings.
static Repository getRepository(String uri)
          Returns the repository identified by the given URI.
static Iterable<Row> getRows(QueryResult result)
          Calls QueryResult.getRows() on the given query result and returns the resulting RowIterator as an Iterable instance for use in a Java 5 for-each loop.
static Iterable<Node> getSharedSet(Node node)
          Calls Node.getSharedSet() on the given node and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.
static Iterable<Property> getWeakReferences(Node node)
          Calls Node.getWeakReferences() on the given node and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.
static Iterable<Property> getWeakReferences(Node node, String name)
          Calls Node.getReferences(String) on the given node and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.
static Node putFile(Node parent, String name, String mime, InputStream data)
          Creates or updates the named child of the given node.
static Node putFile(Node parent, String name, String mime, InputStream data, Calendar date)
          Creates or updates the named child of the given node.
 InputStream readFile(Node node)
          Returns a stream for reading the contents of the file stored at the given node.
 void readFile(Node node, OutputStream output)
          Writes the contents of file stored at the given node to the given stream.
 void setLastModified(Node node, Calendar date)
          Sets the last modified date of the given file node.
static String toString(Item item)
          Returns a string representation of the given item.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

REPOSITORY_URI

public static final String REPOSITORY_URI
The repository URI parameter name used by the getRepository(String) method. All RepositoryFactory implementations that want to support this repository access convention should implement processing of this parameter.

Client applications are recommended to use the getRepository(String) method instead of directly referencing this constant unless they explicitly want to pass also other RepositoryFactory parameters through the getRepository(Map) method.

See Also:
Constant Field Values

NO_VALUES

public static final Value[] NO_VALUES
A pre-allocated empty array of values.

Since:
Apache Jackrabbit 2.3
Method Detail

getRepository

public static Repository getRepository()
                                throws RepositoryException
Returns the default repository of the current environment. Implemented by calling getRepository(Map) with a null parameter map.

Returns:
default repository
Throws:
RepositoryException - if a default repository is not available or can not be accessed
See Also:
RepositoryFactory.getRepository(Map)

getRepository

public static Repository getRepository(Map<String,String> parameters)
                                throws RepositoryException
Looks up the available repository factories and returns the repository that one of the factories returns for the given settings.

Note that unlike RepositoryFactory.getRepository(Map) this method will throw an exception instead of returning null if the given parameters can not be interpreted.

Parameters:
parameters - repository settings
Returns:
repository reference
Throws:
RepositoryException - if the repository can not be accessed, or if an appropriate repository factory is not available

getRepository

public static Repository getRepository(String uri)
                                throws RepositoryException
Returns the repository identified by the given URI. This feature is implemented by calling the getRepository(Map) method with the REPOSITORY_URI parameter set to the given URI. Any query parameters are moved from the URI to the parameter map.

See the documentation of the repository implementation you want to use for whether it supports this repository URI convention and for what the repository URI should look like. For example, Jackrabbit 2.0 supports the following types of repository URIs:

http(s)://...
A remote repository connection using SPI2DAVex with the given URL. See the jackrabbit-jcr2dav component for more details.
file://...
An embedded Jackrabbit repository located in the given directory. See the jackrabbit-core component for more details.
jndi:...
JNDI lookup for the named repository. See the JndiRepositoryFactory class for more details.

Parameters:
uri - repository URI
Returns:
repository instance
Throws:
RepositoryException - if the repository can not be accessed, or if the given URI is unknown or invalid

getSharedSet

public static Iterable<Node> getSharedSet(Node node)
                                   throws RepositoryException
Calls Node.getSharedSet() on the given node and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - shared node
Returns:
nodes in the shared set
Throws:
RepositoryException - if the Node.getSharedSet() call fails
See Also:
NodeIterable

getChildNodes

public static Iterable<Node> getChildNodes(Node node)
                                    throws RepositoryException
Calls Node.getNodes() on the given node and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - parent node
Returns:
child nodes
Throws:
RepositoryException - if the Node.getNodes() call fails
See Also:
NodeIterable

getChildNodes

public static Iterable<Node> getChildNodes(Node node,
                                           String pattern)
                                    throws RepositoryException
Calls Node.getNodes(String) on the given node with the given name pattern and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - parent node
pattern - node name pattern
Returns:
matching child nodes
Throws:
RepositoryException - if the Node.getNodes(String) call fails
See Also:
NodeIterable

getChildNodes

public static Iterable<Node> getChildNodes(Node node,
                                           String[] globs)
                                    throws RepositoryException
Calls Node.getNodes(String[]) on the given node with the given name globs and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - parent node
globs - node name pattern
Returns:
matching child nodes
Throws:
RepositoryException - if the Node.getNodes(String[]) call fails
See Also:
NodeIterable

getProperties

public static Iterable<Property> getProperties(Node node)
                                        throws RepositoryException
Calls Node.getProperties() on the given node and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - node
Returns:
properties of the node
Throws:
RepositoryException - if the Node.getProperties() call fails
See Also:
PropertyIterable

getProperties

public static Iterable<Property> getProperties(Node node,
                                               String pattern)
                                        throws RepositoryException
Calls Node.getProperties(String) on the given node with the given name pattern and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - node
pattern - property name pattern
Returns:
matching properties of the node
Throws:
RepositoryException - if the Node.getProperties(String) call fails
See Also:
PropertyIterable

getProperties

public static Iterable<Property> getProperties(Node node,
                                               String[] globs)
                                        throws RepositoryException
Calls Node.getProperties(String[]) on the given node with the given name globs and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - node
globs - property name globs
Returns:
matching properties of the node
Throws:
RepositoryException - if the Node.getProperties(String[]) call fails
See Also:
PropertyIterable

getReferences

public static Iterable<Property> getReferences(Node node)
                                        throws RepositoryException
Calls Node.getReferences() on the given node and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - reference target
Returns:
references that point to the given node
Throws:
RepositoryException - if the Node.getReferences() call fails
See Also:
PropertyIterable

getReferences

public static Iterable<Property> getReferences(Node node,
                                               String name)
                                        throws RepositoryException
Calls Node.getReferences(String) on the given node and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - reference target
name - reference property name
Returns:
references with the given name that point to the given node
Throws:
RepositoryException - if the Node.getReferences(String) call fails
See Also:
PropertyIterable

getWeakReferences

public static Iterable<Property> getWeakReferences(Node node)
                                            throws RepositoryException
Calls Node.getWeakReferences() on the given node and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - reference target
Returns:
weak references that point to the given node
Throws:
RepositoryException - if the Node.getWeakReferences() call fails
See Also:
PropertyIterable

getWeakReferences

public static Iterable<Property> getWeakReferences(Node node,
                                                   String name)
                                            throws RepositoryException
Calls Node.getReferences(String) on the given node and returns the resulting PropertyIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
node - reference target
name - reference property name
Returns:
weak references with the given name that point to the given node
Throws:
RepositoryException - if the Node.getWeakReferences(String) call fails
See Also:
PropertyIterable

getNodes

public static Iterable<Node> getNodes(QueryResult result)
                               throws RepositoryException
Calls QueryResult.getNodes() on the given query result and returns the resulting NodeIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
result - query result
Returns:
nodes in the query result
Throws:
RepositoryException - if the QueryResult.getNodes() call fails
See Also:
NodeIterable

getRows

public static Iterable<Row> getRows(QueryResult result)
                             throws RepositoryException
Calls QueryResult.getRows() on the given query result and returns the resulting RowIterator as an Iterable instance for use in a Java 5 for-each loop.

Parameters:
result - query result
Returns:
rows in the query result
Throws:
RepositoryException - if the QueryResult.getRows() call fails
See Also:
RowIterable

getOrAddNode

public static Node getOrAddNode(Node parent,
                                String name)
                         throws RepositoryException
Returns the named child of the given node, creating the child if it does not already exist. If the child node gets added, then its type will be determined by the child node definitions associated with the parent node. The caller is expected to take care of saving or discarding any transient changes.

Parameters:
parent - parent node
name - name of the child node
Returns:
the child node
Throws:
RepositoryException - if the child node can not be accessed or created
See Also:
Node.getNode(String), Node.addNode(String)

getOrAddNode

public static Node getOrAddNode(Node parent,
                                String name,
                                String type)
                         throws RepositoryException
Returns the named child of the given node, creating the child if it does not already exist. If the child node gets added, then it is created with the given node type. The caller is expected to take care of saving or discarding any transient changes.

Parameters:
parent - parent node
name - name of the child node
type - type of the child node, ignored if the child already exists
Returns:
the child node
Throws:
RepositoryException - if the child node can not be accessed or created
See Also:
Node.getNode(String), Node.addNode(String, String), Node.isNodeType(String)

getOrAddFolder

public static Node getOrAddFolder(Node parent,
                                  String name)
                           throws RepositoryException
Returns the named child of the given node, creating it as an nt:folder node if it does not already exist. The caller is expected to take care of saving or discarding any transient changes.

Note that the type of the returned node is not guaranteed to match nt:folder in case the node already existed. The caller can use an explicit Node.isNodeType(String) check if needed, or simply use a data-first approach and not worry about the node type until a constraint violation is encountered.

Parameters:
parent - parent node
name - name of the child node
Returns:
the child node
Throws:
RepositoryException - if the child node can not be accessed or created

putFile

public static Node putFile(Node parent,
                           String name,
                           String mime,
                           InputStream data)
                    throws RepositoryException
Creates or updates the named child of the given node. If the child does not already exist, then it is created using the nt:file node type. This file child node is returned from this method.

If the file node does not already contain a jcr:content child, then one is created using the nt:resource node type. The following properties are set on the jcr:content node:

jcr:mimeType
media type
jcr:encoding (optional)
charset parameter of the media type, if any
jcr:lastModified
current time
jcr:data
binary content

Note that the types of the returned node or the jcr:content child are not guaranteed to match nt:file and nt:resource in case the nodes already existed. The caller can use an explicit Node.isNodeType(String) check if needed, or simply use a data-first approach and not worry about the node type until a constraint violation is encountered.

The given binary content stream is closed by this method.

Parameters:
parent - parent node
name - name of the file
mime - media type of the file
data - binary content of the file
Returns:
the child node
Throws:
RepositoryException - if the child node can not be created or updated

putFile

public static Node putFile(Node parent,
                           String name,
                           String mime,
                           InputStream data,
                           Calendar date)
                    throws RepositoryException
Creates or updates the named child of the given node. If the child does not already exist, then it is created using the nt:file node type. This file child node is returned from this method.

If the file node does not already contain a jcr:content child, then one is created using the nt:resource node type. The following properties are set on the jcr:content node:

jcr:mimeType
media type
jcr:encoding (optional)
charset parameter of the media type, if any
jcr:lastModified
date of last modification
jcr:data
binary content

Note that the types of the returned node or the jcr:content child are not guaranteed to match nt:file and nt:resource in case the nodes already existed. The caller can use an explicit Node.isNodeType(String) check if needed, or simply use a data-first approach and not worry about the node type until a constraint violation is encountered.

The given binary content stream is closed by this method.

Parameters:
parent - parent node
name - name of the file
mime - media type of the file
data - binary content of the file
date - date of last modification
Returns:
the child node
Throws:
RepositoryException - if the child node can not be created or updated

readFile

public InputStream readFile(Node node)
                     throws RepositoryException
Returns a stream for reading the contents of the file stored at the given node. This method works with both on nt:file and nt:resource and on any other similar node types, as it only looks for the jcr:data property or a jcr:content child node.

The returned stream contains a reference to the underlying Binary value instance that will be disposed when the stream is closed. It is the responsibility of the caller to close the stream once it is no longer needed.

Parameters:
node - node to be read
Returns:
stream for reading the file contents
Throws:
RepositoryException - if the file can not be accessed
Since:
Apache Jackrabbit 2.3

readFile

public void readFile(Node node,
                     OutputStream output)
              throws RepositoryException,
                     IOException
Writes the contents of file stored at the given node to the given stream. Similar file handling logic is used as in the readFile(Node) method.

Parameters:
node - node to be read
output - to which the file contents are written
Throws:
RepositoryException - if the file can not be accessed
IOException - if the file can not be read or written
Since:
Apache Jackrabbit 2.3

getLastModified

public Calendar getLastModified(Node node)
                         throws RepositoryException
Returns the last modified date of the given file node. The value is read from the jcr:lastModified property of this node or alternatively from a jcr:content child node.

Parameters:
node - file node
Returns:
last modified date, or null if not available
Throws:
RepositoryException - if the last modified date can not be accessed
Since:
Apache Jackrabbit 2.3

setLastModified

public void setLastModified(Node node,
                            Calendar date)
                     throws RepositoryException
Sets the last modified date of the given file node. The value is written to the jcr:lastModified property of a jcr:content child node or this node if such a child does not exist.

Parameters:
node - file node
date - modified date
Throws:
RepositoryException - if the last modified date can not be set
Since:
Apache Jackrabbit 2.3

toString

public static String toString(Item item)
Returns a string representation of the given item. The returned string is designed to be easily readable while providing maximum amount of information for logging and debugging purposes.

The returned string is not meant to be parsed and the exact contents can change in future releases. The current string representation of a node is "/path/to/node [type]" and the representation of a property is "@name = value(s)". Binary values are expressed like "<123 bytes>" and other values as their standard binary representation. Multi-valued properties have their values listed in like "[ v1, v2, v3, ... ]". No more than the three first values are included. Long string values are truncated.

Parameters:
item - given node or property
Returns:
string representation of the given item

getPropertyType

public static int getPropertyType(String name)
                           throws IllegalArgumentException
Returns the numeric constant value of the property type with the specified name. This method is like PropertyType.valueFromName(String), but the name lookup is case insensitive.

Parameters:
name - name of the property type (case insensitive)
Returns:
property type constant
Throws:
IllegalArgumentException - if the given name is not a valid property type name
Since:
Apache Jackrabbit 2.3

getOrCreateByPath

public static Node getOrCreateByPath(String absolutePath,
                                     String nodeType,
                                     Session session)
                              throws RepositoryException
Creates or gets the Node at the given Path. In case it has to create the Node all non-existent intermediate path-elements will be created with the given NodeType.

Changes made are not saved by this method, so session.save() has to be called to persist them.

Parameters:
absolutePath - absolute path to create
nodeType - to use for creation of nodes If null the node type is determined by the child node definitions of the parent node.
session - to use
Returns:
the Node at path
Throws:
RepositoryException - in case of exception accessing the Repository

getOrCreateByPath

public static Node getOrCreateByPath(String absolutePath,
                                     String intermediateNodeType,
                                     String nodeType,
                                     Session session,
                                     boolean autoSave)
                              throws RepositoryException
Creates or gets the Node at the given Path. In case it has to create the Node all non-existent intermediate path-elements will be created with the given intermediate node type and the returned node will be created with the given nodeType.

Parameters:
absolutePath - absolute path to create
intermediateNodeType - to use for creation of intermediate nodes. If null the node type is determined by the child node definitions of the parent node.
nodeType - to use for creation of the final node. If null the node type is determined by the child node definitions of the parent node.
session - to use
autoSave - Should save be called when a new node is created?
Returns:
the Node at absolutePath
Throws:
RepositoryException - in case of exception accessing the Repository

getOrCreateUniqueByPath

public static Node getOrCreateUniqueByPath(String pathHint,
                                           String nodeType,
                                           Session session)
                                    throws RepositoryException
Creates a Node at the given Path. In case it has to create the Node all non-existent intermediate path-elements will be created with the given intermediate node type and the returned node will be created with the given nodeType.

If the path points to an existing node, the leaf node name will be regarded as a name hint and a unique node name will be created by appending a number to the given name (eg. /some/path/foobar2). Please note that the uniqueness check is not an atomic JCR operation, so it is possible that you get a RepositoryException (path already exists) if another concurrent session created the same node in the meantime.

Changes made are not saved by this method, so session.save() has to be called to persist them.

Parameters:
pathHint - path to create
nodeType - to use for creation of nodes. . If null the node type is determined by the child node definitions of the parent node.
session - to use
Returns:
the newly created Node
Throws:
RepositoryException - in case of exception accessing the Repository

getOrCreateByPath

public static Node getOrCreateByPath(String absolutePath,
                                     boolean createUniqueLeaf,
                                     String intermediateNodeType,
                                     String nodeType,
                                     Session session,
                                     boolean autoSave)
                              throws RepositoryException
Creates or gets the Node at the given Path. In case it has to create the Node all non-existent intermediate path-elements will be created with the given intermediate node type and the returned node will be created with the given nodeType.

If the parameter createUniqueLeaf is set, it will not get an existing node but rather try to create a unique node by appending a number to the last path element (leaf node). Please note that the uniqueness check is not an atomic JCR operation, so it is possible that you get a RepositoryException (path already exists) if another concurrent session created the same node in the meantime.

Parameters:
absolutePath - absolute path to create
createUniqueLeaf - whether the leaf of the path should be regarded as a name hint and a unique node name should be created by appending a number to the given name (eg. /some/path/foobar2)
intermediateNodeType - to use for creation of intermediate nodes. If null the node type is determined by the child node definitions of the parent node.
nodeType - to use for creation of the final node. If null the node type is determined by the child node definitions of the parent node.
session - to use
autoSave - Should save be called when a new node is created?
Returns:
the Node at absolutePath
Throws:
RepositoryException - in case of exception accessing the Repository

getOrCreateUniqueByPath

public static Node getOrCreateUniqueByPath(Node parent,
                                           String nodeNameHint,
                                           String nodeType)
                                    throws RepositoryException
Creates or gets the Node at the given Path. In case it has to create the Node all non-existent intermediate path-elements will be created with the given intermediate node type and the returned node will be created with the given nodeType.

If the node name points to an existing node, the node name will be regarded as a name hint and a unique node name will be created by appending a number to the given name (eg. /some/path/foobar2). Please note that the uniqueness check is not an atomic JCR operation, so it is possible that you get a RepositoryException (path already exists) if another concurrent session created the same node in the meantime.

Changes made are not saved by this method, so session.save() has to be called to persist them.

Parameters:
parent - existing parent node for the new node
nodeNameHint - name hint for the new node
nodeType - to use for creation of the node. If null the node type is determined by the child node definitions of the parent node.
Returns:
the newly created Node
Throws:
RepositoryException - in case of exception accessing the Repository

getOrCreateByPath

public static Node getOrCreateByPath(Node baseNode,
                                     String path,
                                     boolean createUniqueLeaf,
                                     String intermediateNodeType,
                                     String nodeType,
                                     boolean autoSave)
                              throws RepositoryException
Creates or gets the Node at the given path relative to the baseNode. In case it has to create the Node all non-existent intermediate path-elements will be created with the given intermediate node type and the returned node will be created with the given nodeType.

If the parameter createUniqueLeaf is set, it will not get an existing node but rather try to create a unique node by appending a number to the last path element (leaf node). Please note that the uniqueness check is not an atomic JCR operation, so it is possible that you get a RepositoryException (path already exists) if another concurrent session created the same node in the meantime.

Parameters:
baseNode - existing node that should be the base for the relative path
path - relative path to create
createUniqueLeaf - whether the leaf of the path should be regarded as a name hint and a unique node name should be created by appending a number to the given name (eg. /some/path/foobar2)
intermediateNodeType - to use for creation of intermediate nodes. If null the node type is determined by the child node definitions of the parent node.
nodeType - to use for creation of the final node. If null the node type is determined by the child node definitions of the parent node.
autoSave - Should save be called when a new node is created?
Returns:
the Node at path
Throws:
RepositoryException - in case of exception accessing the Repository


Copyright © 2004-2011 The Apache Software Foundation. All Rights Reserved.