1616package com .marklogic .client ;
1717
1818import java .io .Serializable ;
19+ import java .util .Set ;
1920
2021import javax .net .ssl .SSLContext ;
2122import javax .net .ssl .SSLException ;
2526
2627import com .marklogic .client .extra .httpclient .HttpClientConfigurator ;
2728import com .marklogic .client .impl .DatabaseClientImpl ;
29+ import com .marklogic .client .impl .HandleFactoryRegistryImpl ;
2830import com .marklogic .client .impl .JerseyServices ;
31+ import com .marklogic .client .io .marker .ContentHandle ;
32+ import com .marklogic .client .io .marker .ContentHandleFactory ;
2933
3034/**
3135 * A Database Client Factory configures a database client for making
@@ -35,6 +39,8 @@ public class DatabaseClientFactory {
3539 static final private Logger logger = LoggerFactory .getLogger (DatabaseClientFactory .class );
3640
3741 static private ClientConfigurator <?> clientConfigurator ;
42+ static private HandleFactoryRegistry handleRegistry =
43+ HandleFactoryRegistryImpl .newDefault ();
3844
3945 /**
4046 * Authentication enumerates the methods for verifying a user and
@@ -116,6 +122,64 @@ public String getName() {
116122 }
117123 }
118124
125+ /**
126+ * A HandleFactoryRegistry associates IO representation classes
127+ * with handle factories. The API uses the registry to create
128+ * a content handle to act as an adapter for a supported
129+ * IO representation class. The IO class and its instances can
130+ * then be passed directly to convenience methods.
131+ * The default registry associates the content handles provided
132+ * by the API and the supported IO representation classes.
133+ * Create instances of this interface only if you need to modify
134+ * the default registry.
135+ * @see DatabaseClientFactory#getHandleRegistry()
136+ * @see DatabaseClientFactory.Bean#getHandleRegistry()
137+ */
138+ public interface HandleFactoryRegistry {
139+ /**
140+ * Associates a factory for content handles with the classes
141+ * for IO representations known to the factory.
142+ * @param factory a factory for creating content handle instances
143+ */
144+ public void register (ContentHandleFactory factory );
145+ /**
146+ * Associates a factory for content handles with the specified classes
147+ * for IO representations.
148+ * @param factory a factory for creating content handle instances
149+ * @param ioClasses the IO classes for which the factory should create handles
150+ */
151+ public void register (ContentHandleFactory factory , Class <?>... ioClasses );
152+ /**
153+ * Returns whether the registry associates the class with a factory.
154+ * @param ioClass the class for an IO representation
155+ * @return true if a factory has been registered
156+ */
157+ public boolean isRegistered (Class <?> ioClass );
158+ /**
159+ * Returns the classes for the IO representations for which a factory
160+ * has been registered.
161+ * @return the IO classes
162+ */
163+ public Set <Class <?>> listRegistered ();
164+ /**
165+ * Creates a ContentHandle if the registry has a factory
166+ * for the class of the IO representation.
167+ * @param type the class for an IO representation
168+ * @return a content handle or null if no factory supports the class
169+ */
170+ public <C > ContentHandle <C > makeHandle (Class <C > type );
171+ /**
172+ * Removes the classes from the registry
173+ * @param ioClasses one or more registered classes for an IO representation
174+ */
175+ public void unregister (Class <?>... ioClasses );
176+ /**
177+ * Create a copy of the current registry
178+ * @return a copy of the current registry
179+ */
180+ public HandleFactoryRegistry copy ();
181+ }
182+
119183 /**
120184 * A ClientConfigurator provides custom configuration for the communication library
121185 * used to sending client requests and receiving server responses.
@@ -133,22 +197,6 @@ public interface ClientConfigurator<T> {
133197 private DatabaseClientFactory () {
134198 }
135199
136- /**
137- * Adds a listener that provides custom configuration when a communication library
138- * is created.
139- * @see com.marklogic.client.extra.httpclient.HttpClientConfigurator
140- * @param configurator the listener for configuring the communication library
141- */
142- static public void addConfigurator (ClientConfigurator <?> configurator ) {
143- if (!HttpClientConfigurator .class .isInstance (configurator )) {
144- throw new IllegalArgumentException (
145- "Configurator must implement HttpClientConfigurator"
146- );
147- }
148-
149- clientConfigurator = configurator ;
150- }
151-
152200 /**
153201 * Creates a client to access the database by means of a REST server
154202 * without any authentication. Such clients can be convenient for
@@ -183,7 +231,7 @@ static public DatabaseClient newClient(String host, int port, String user, Strin
183231 * @param user the user with read, write, or administrative privileges
184232 * @param password the password for the user
185233 * @param type the type of authentication applied to the request
186- * @param context the SSL content for authenticating with the server
234+ * @param context the SSL context for authenticating with the server
187235 * @return a new client for making database requests
188236 */
189237 static public DatabaseClient newClient (String host , int port , String user , String password , Authentication type , SSLContext context ) {
@@ -197,11 +245,16 @@ static public DatabaseClient newClient(String host, int port, String user, Strin
197245 * @param user the user with read, write, or administrative privileges
198246 * @param password the password for the user
199247 * @param type the type of authentication applied to the request
200- * @param context the SSL content for authenticating with the server
248+ * @param context the SSL context for authenticating with the server
201249 * @param verifier a callback for checking hostnames
202250 * @return a new client for making database requests
203251 */
204252 static public DatabaseClient newClient (String host , int port , String user , String password , Authentication type , SSLContext context , SSLHostnameVerifier verifier ) {
253+ DatabaseClientImpl client = newClientImpl (host , port , user , password , type , context , verifier );
254+ client .setHandleRegistry (getHandleRegistry ().copy ());
255+ return client ;
256+ }
257+ static private DatabaseClientImpl newClientImpl (String host , int port , String user , String password , Authentication type , SSLContext context , SSLHostnameVerifier verifier ) {
205258 logger .debug ("Creating new database client for server at " +host +":" +port );
206259 JerseyServices services = new JerseyServices ();
207260 services .connect (host , port , user , password , type , context , verifier );
@@ -215,6 +268,48 @@ static public DatabaseClient newClient(String host, int port, String user, Strin
215268 return new DatabaseClientImpl (services );
216269 }
217270
271+ /**
272+ * Returns the default registry with factories for creating handles
273+ * as adapters for IO representations. To create custom registries,
274+ * use
275+ * @return the default registry
276+ */
277+ static public HandleFactoryRegistry getHandleRegistry () {
278+ return handleRegistry ;
279+ }
280+ /**
281+ * Removes the current registered associations so the
282+ * handle registry is empty.
283+ */
284+ static public void clearHandleRegistry () {
285+ handleRegistry = new HandleFactoryRegistryImpl ();
286+ }
287+ /**
288+ * Initializes a handle registry with the default associations
289+ * between the content handles provided by the API and the supported
290+ * IO representation classes. Use this method only after clearing
291+ * or overwriting associations in the handle registry.
292+ */
293+ static public void registerDefaultHandles () {
294+ HandleFactoryRegistryImpl .registerDefaults (getHandleRegistry ());
295+ }
296+
297+ /**
298+ * Adds a listener that provides custom configuration when a communication library
299+ * is created.
300+ * @see com.marklogic.client.extra.httpclient.HttpClientConfigurator
301+ * @param configurator the listener for configuring the communication library
302+ */
303+ static public void addConfigurator (ClientConfigurator <?> configurator ) {
304+ if (!HttpClientConfigurator .class .isInstance (configurator )) {
305+ throw new IllegalArgumentException (
306+ "Configurator must implement HttpClientConfigurator"
307+ );
308+ }
309+
310+ clientConfigurator = configurator ;
311+ }
312+
218313 /**
219314 * A Database Client Factory Bean provides an object for specifying configuration
220315 * before creating a client to make database requests.
@@ -240,13 +335,16 @@ static public DatabaseClient newClient(String host, int port, String user, Strin
240335 static public class Bean implements Serializable {
241336 private static final long serialVersionUID = 1L ;
242337
243- private String host ;
244- private int port ;
245- private String user ;
246- private String password ;
247- private Authentication authentication ;
248- transient private SSLContext context ;
249- transient private SSLHostnameVerifier verifier ;
338+ private String host ;
339+ private int port ;
340+ private String user ;
341+ private String password ;
342+ private Authentication authentication ;
343+ private HandleFactoryRegistry handleRegistry =
344+ HandleFactoryRegistryImpl .newDefault ();
345+
346+ transient private SSLContext context ;
347+ transient private SSLHostnameVerifier verifier ;
250348
251349 /**
252350 * Zero-argument constructor for bean applications. Other
@@ -379,6 +477,31 @@ public void setVerifier(SSLHostnameVerifier verifier) {
379477 this .verifier = verifier ;
380478 }
381479
480+ /**
481+ * Returns the registry for associating
482+ * IO representation classes with handle factories.
483+ * @return the registry instance
484+ */
485+ public HandleFactoryRegistry getHandleRegistry () {
486+ return handleRegistry ;
487+ }
488+ /**
489+ * Removes the current registered associations so the
490+ * handle registry is empty.
491+ */
492+ public void clearHandleRegistry () {
493+ this .handleRegistry = new HandleFactoryRegistryImpl ();
494+ }
495+ /**
496+ * Initializes a handle registry with the default associations
497+ * between the content handles provided by the API and the supported
498+ * IO representation classes. Use this method only after clearing
499+ * or overwriting associations in the handle registry.
500+ */
501+ public void registerDefaultHandles () {
502+ HandleFactoryRegistryImpl .registerDefaults (getHandleRegistry ());
503+ }
504+
382505 /**
383506 * Creates a client for bean applications based on the properties.
384507 * Other applications can use the static newClient() factory methods
@@ -387,9 +510,10 @@ public void setVerifier(SSLHostnameVerifier verifier) {
387510 * @return a new client for making database requests
388511 */
389512 public DatabaseClient newClient () {
390- return DatabaseClientFactory .newClient (
391- host , port , user , password , authentication , context , verifier
392- );
513+ DatabaseClientImpl client = newClientImpl (host , port , user , password , authentication , context , verifier );
514+ client .setHandleRegistry (getHandleRegistry ().copy ());
515+
516+ return client ;
393517 }
394518 }
395519}
0 commit comments