001: /*
002: * Copyright 2007 Day Management AG, Switzerland. All rights reserved.
003: */
004: package javax.jcr;
005:
006: import javax.imageio.spi.ServiceRegistry;
007: import java.util.Map;
008: import java.util.Iterator;
009: import java.util.Collections;
010:
011: /**
012: * <code>RepositoryFactory</code> is a factory class for Repository
013: * implementations.
014: * <p/>
015: * A concrete implementation of this class must have a zero-argument
016: * constructor. Repository factories may be installed in an instance of the Java
017: * platform as extensions, that is, jar files placed into any of the usual
018: * extension directories. Factories may also be made available by adding them to
019: * the applet or application class path or by some other platform-specific
020: * means. Repository factories are looked up via the current thread's context
021: * class loader.
022: * <p/>
023: * A repository factory should identify itself with a factory-configuration file
024: * named javax.jcr.RepositoryFactory in the resource directory
025: * META-INF/services. The file should contain a list of fully-qualified concrete
026: * repository-factory class names, one per line. A line is terminated by any one
027: * of a line feed ('\n'), a carriage return ('\r'), or a carriage return
028: * followed immediately by a line feed. Space and tab characters surrounding
029: * each name, as well as blank lines, are ignored. The comment character is '#'
030: * ('\u0023'); on each line all characters following the first comment character
031: * are ignored. The file must be encoded in UTF-8.
032: * <p/>
033: * If a particular concrete repository factory class is named in more than one
034: * configuration file, or is named in the same configuration file more than
035: * once, then the duplicates will be ignored. The configuration file naming a
036: * particular factory need not be in the same jar file or other distribution
037: * unit as the factory itself. The factory must be accessible from the same
038: * class loader that was initially queried to locate the configuration file;
039: * this is not necessarily the class loader that loaded the file.
040: * <p/>
041: * <b>Examples how to obtain repository instances</b>
042: * <p/>
043: * Use repository factory based on parameters:
044: * <code>
045: * <pre>
046: * Map parameters = new HashMap();
047: * parameters.put("address", "vendor://localhost:9999/myrepo");
048: * Repository repo = RepositoryFactory.getRepository(parameters);
049: * </pre>
050: * </code>
051: * Get a default repository available in this environment:
052: * <code>
053: * <pre>
054: * Repository repo = RepositoryFactory.getRepository();
055: * </pre>
056: * </code>
057: * Manually instanciate a specific repository factory and connect to the
058: * repository:
059: * <code>
060: * <pre>
061: * Map parameters = new HashMap();
062: * parameters.put("address", "vendor://localhost:9999/myrepo");
063: * RepositoryFactory factory = new com.vendor.RepositoryFactory();
064: * Repository repo = factory.connect(parameters);
065: * </pre>
066: * </code>
067: */
068: public abstract class RepositoryFactory {
069:
070: /**
071: * Attempts to establish a connection to a repository described by the given
072: * parameters. The implementation should return <code>null</code> if it does
073: * not understand the given parameters. The implementation may also return
074: * <code>null</code> if a default repository instance is requested
075: * (indicated by <code>null</code> <code>parameters</code>) and this factory
076: * is not able to identify a default repository.
077: * <p/>
078: * An implementation should throw an <code>RepositoryException</code> if it
079: * is the right factory but has trouble connecting to the repository.
080: * <p/>
081: * An implementation of this method must be thread-safe.
082: *
083: * @param parameters map of arbitrary string key/value pairs as repository
084: * arguments or <code>null</code> if none are provided and
085: * a client whishes to connect to a default repository.
086: * @return a repository instance or <code>null</code> if this implementation
087: * does not understand the passed <code>properties</code>.
088: * @throws RepositoryException if an error occurs while connecting to the
089: * repository.
090: * @see RepositoryFactory#getRepository(java.util.Map)
091: */
092: public abstract Repository connect(Map parameters)
093: throws RepositoryException;
094:
095: /**
096: * Attempts to establish a connection to a repository using the given
097: * <code>parameters</code>. The keys and values of the parameters are
098: * implementation specific.
099: *
100: * @param parameters map of arbitrary string key/value pairs as repository
101: * arguments or <code>null</code> if none are provided and
102: * a client whishes to connect to a default repository.
103: * @return a repository instance.
104: * @throws RepositoryException if getRepository fails or if no suitable
105: * repository is found.
106: */
107: public static Repository getRepository(Map parameters)
108: throws RepositoryException {
109: parameters = Collections.unmodifiableMap(parameters);
110: Iterator it = ServiceRegistry
111: .lookupProviders(RepositoryFactory.class);
112: while (it.hasNext()) {
113: RepositoryFactory factory = (RepositoryFactory) it.next();
114: Repository repo = factory.connect(parameters);
115: if (repo != null) {
116: return repo;
117: }
118: }
119: throw new RepositoryException("No suitable Repository found");
120: }
121:
122: /**
123: * Returns the first default Repository returned by a RepositoryFactory.
124: *
125: * @return a default repository instance.
126: * @throws RepositoryException if no factory returned a default repository
127: * or if an error occurs.
128: */
129: public static Repository getRepository() throws RepositoryException {
130: Iterator it = ServiceRegistry
131: .lookupProviders(RepositoryFactory.class);
132: while (it.hasNext()) {
133: RepositoryFactory factory = (RepositoryFactory) it.next();
134: Repository repo = factory.connect(null);
135: if (repo != null) {
136: return repo;
137: }
138: }
139: throw new RepositoryException("No default Repository found");
140: }
141: }
|