001 /*
002 * JBoss DNA (http://www.jboss.org/dna)
003 * See the COPYRIGHT.txt file distributed with this work for information
004 * regarding copyright ownership. Some portions may be licensed
005 * to Red Hat, Inc. under one or more contributor license agreements.
006 * See the AUTHORS.txt file in the distribution for a full listing of
007 * individual contributors.
008 *
009 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010 * is licensed to you under the terms of the GNU Lesser General Public License as
011 * published by the Free Software Foundation; either version 2.1 of
012 * the License, or (at your option) any later version.
013 *
014 * JBoss DNA is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 * Lesser General Public License for more details.
018 *
019 * You should have received a copy of the GNU Lesser General Public
020 * License along with this software; if not, write to the Free
021 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023 */
024 package org.jboss.dna.connector.jbosscache;
025
026 import java.io.ByteArrayInputStream;
027 import java.io.ByteArrayOutputStream;
028 import java.io.IOException;
029 import java.io.ObjectInputStream;
030 import java.io.ObjectOutputStream;
031 import java.util.Enumeration;
032 import java.util.HashMap;
033 import java.util.HashSet;
034 import java.util.Hashtable;
035 import java.util.List;
036 import java.util.Map;
037 import java.util.Set;
038 import java.util.UUID;
039 import javax.naming.BinaryRefAddr;
040 import javax.naming.Context;
041 import javax.naming.InitialContext;
042 import javax.naming.NamingException;
043 import javax.naming.RefAddr;
044 import javax.naming.Reference;
045 import javax.naming.Referenceable;
046 import javax.naming.StringRefAddr;
047 import javax.naming.spi.ObjectFactory;
048 import net.jcip.annotations.ThreadSafe;
049 import org.jboss.cache.Cache;
050 import org.jboss.cache.CacheFactory;
051 import org.jboss.cache.DefaultCacheFactory;
052 import org.jboss.dna.common.i18n.I18n;
053 import org.jboss.dna.common.util.StringUtil;
054 import org.jboss.dna.graph.DnaLexicon;
055 import org.jboss.dna.graph.cache.CachePolicy;
056 import org.jboss.dna.graph.connector.RepositoryConnection;
057 import org.jboss.dna.graph.connector.RepositoryContext;
058 import org.jboss.dna.graph.connector.RepositorySource;
059 import org.jboss.dna.graph.connector.RepositorySourceCapabilities;
060 import org.jboss.dna.graph.connector.RepositorySourceException;
061 import org.jboss.dna.graph.property.Name;
062
063 /**
064 * A repository source that uses a JBoss Cache instance to manage the content. This source is capable of using an existing
065 * {@link Cache} instance or creating a new instance. This process is controlled entirely by the JavaBean properties of the
066 * JBossCacheSource instance.
067 * <p>
068 * This source first attempts to find an existing cache in {@link #getCacheJndiName() JNDI}. If none is found, then it attempts to
069 * create a cache instance using the {@link CacheFactory} found in {@link #getCacheFactoryJndiName() JNDI} (or the
070 * {@link DefaultCacheFactory} if no such factory is available) and the {@link #getCacheConfigurationName() cache configuration
071 * name} if supplied or the default configuration if not set.
072 * </p>
073 * <p>
074 * Like other {@link RepositorySource} classes, instances of JBossCacheSource can be placed into JNDI and do support the creation
075 * of {@link Referenceable JNDI referenceable} objects and resolution of references into JBossCacheSource.
076 * </p>
077 *
078 * @author Randall Hauch
079 */
080 @ThreadSafe
081 public class JBossCacheSource implements RepositorySource, ObjectFactory {
082
083 private static final long serialVersionUID = 2L;
084 /**
085 * The default limit is {@value} for retrying {@link RepositoryConnection connection} calls to the underlying source.
086 */
087 public static final int DEFAULT_RETRY_LIMIT = 0;
088 public static final String DEFAULT_UUID_PROPERTY_NAME = DnaLexicon.UUID.getString();
089
090 /**
091 * The initial {@link #getNameOfDefaultWorkspace() name of the default workspace} is "{@value} ", unless otherwise specified.
092 */
093 public static final String DEFAULT_NAME_OF_DEFAULT_WORKSPACE = "default";
094
095 protected static final String ROOT_NODE_UUID = "rootNodeUuid";
096 protected static final String SOURCE_NAME = "sourceName";
097 protected static final String DEFAULT_CACHE_POLICY = "defaultCachePolicy";
098 protected static final String CACHE_CONFIGURATION_NAME = "cacheConfigurationName";
099 protected static final String CACHE_FACTORY_JNDI_NAME = "cacheFactoryJndiName";
100 protected static final String CACHE_JNDI_NAME = "cacheJndiName";
101 protected static final String RETRY_LIMIT = "retryLimit";
102 protected static final String DEFAULT_WORKSPACE = "defaultWorkspace";
103 protected static final String PREDEFINED_WORKSPACE_NAMES = "predefinedWorkspaceNames";
104 protected static final String ALLOW_CREATING_WORKSPACES = "allowCreatingWorkspaces";
105
106 private volatile String name;
107 private volatile UUID rootNodeUuid = UUID.randomUUID();
108 private volatile CachePolicy defaultCachePolicy;
109 private volatile String cacheConfigurationName;
110 private volatile String cacheFactoryJndiName;
111 private volatile String cacheJndiName;
112 private volatile int retryLimit = DEFAULT_RETRY_LIMIT;
113 private volatile String defaultWorkspace;
114 private volatile String[] predefinedWorkspaces = new String[] {};
115 private volatile RepositorySourceCapabilities capabilities = new RepositorySourceCapabilities(true, true, false, true, false);
116 private transient JBossCacheWorkspaces workspaces;
117 private transient Context jndiContext;
118
119 /**
120 * Create a repository source instance.
121 */
122 public JBossCacheSource() {
123 }
124
125 /**
126 * {@inheritDoc}
127 *
128 * @see org.jboss.dna.graph.connector.RepositorySource#initialize(org.jboss.dna.graph.connector.RepositoryContext)
129 */
130 public void initialize( RepositoryContext context ) throws RepositorySourceException {
131 }
132
133 /**
134 * {@inheritDoc}
135 */
136 public String getName() {
137 return this.name;
138 }
139
140 /**
141 * {@inheritDoc}
142 *
143 * @see org.jboss.dna.graph.connector.RepositorySource#getCapabilities()
144 */
145 public RepositorySourceCapabilities getCapabilities() {
146 return capabilities;
147 }
148
149 /**
150 * {@inheritDoc}
151 *
152 * @see org.jboss.dna.graph.connector.RepositorySource#getRetryLimit()
153 */
154 public int getRetryLimit() {
155 return retryLimit;
156 }
157
158 /**
159 * {@inheritDoc}
160 *
161 * @see org.jboss.dna.graph.connector.RepositorySource#setRetryLimit(int)
162 */
163 public synchronized void setRetryLimit( int limit ) {
164 retryLimit = limit < 0 ? 0 : limit;
165 }
166
167 /**
168 * Set the name of this source
169 *
170 * @param name the name for this source
171 */
172 public synchronized void setName( String name ) {
173 if (this.name == name || this.name != null && this.name.equals(name)) return; // unchanged
174 this.name = name;
175 }
176
177 /**
178 * Get the default cache policy for this source, or null if the global default cache policy should be used
179 *
180 * @return the default cache policy, or null if this source has no explicit default cache policy
181 */
182 public CachePolicy getDefaultCachePolicy() {
183 return defaultCachePolicy;
184 }
185
186 /**
187 * @param defaultCachePolicy Sets defaultCachePolicy to the specified value.
188 */
189 public synchronized void setDefaultCachePolicy( CachePolicy defaultCachePolicy ) {
190 if (this.defaultCachePolicy == defaultCachePolicy || this.defaultCachePolicy != null
191 && this.defaultCachePolicy.equals(defaultCachePolicy)) return; // unchanged
192 this.defaultCachePolicy = defaultCachePolicy;
193 }
194
195 /**
196 * Get the name in JNDI of a {@link Cache} instance that should be used by this source.
197 * <p>
198 * This source first attempts to find an existing cache in {@link #getCacheJndiName() JNDI}. If none is found, then it
199 * attempts to create a cache instance using the {@link CacheFactory} found in {@link #getCacheFactoryJndiName() JNDI} (or the
200 * {@link DefaultCacheFactory} if no such factory is available) and the {@link #getCacheConfigurationName() cache
201 * configuration name} if supplied or the default configuration if not set.
202 * </p>
203 *
204 * @return the JNDI name of the {@link Cache} instance that should be used, or null if the cache is to be created with a cache
205 * factory {@link #getCacheFactoryJndiName() found in JNDI} using the specified {@link #getCacheConfigurationName()
206 * cache configuration name}.
207 * @see #setCacheJndiName(String)
208 * @see #getCacheConfigurationName()
209 * @see #getCacheFactoryJndiName()
210 */
211 public String getCacheJndiName() {
212 return cacheJndiName;
213 }
214
215 /**
216 * Set the name in JNDI of a {@link Cache} instance that should be used by this source.
217 * <p>
218 * This source first attempts to find an existing cache in {@link #getCacheJndiName() JNDI}. If none is found, then it
219 * attempts to create a cache instance using the {@link CacheFactory} found in {@link #getCacheFactoryJndiName() JNDI} (or the
220 * {@link DefaultCacheFactory} if no such factory is available) and the {@link #getCacheConfigurationName() cache
221 * configuration name} if supplied or the default configuration if not set.
222 * </p>
223 *
224 * @param cacheJndiName the JNDI name of the {@link Cache} instance that should be used, or null if the cache is to be created
225 * with a cache factory {@link #getCacheFactoryJndiName() found in JNDI} using the specified
226 * {@link #getCacheConfigurationName() cache configuration name}.
227 * @see #getCacheJndiName()
228 * @see #getCacheConfigurationName()
229 * @see #getCacheFactoryJndiName()
230 */
231 public synchronized void setCacheJndiName( String cacheJndiName ) {
232 if (this.cacheJndiName == cacheJndiName || this.cacheJndiName != null && this.cacheJndiName.equals(cacheJndiName)) return; // unchanged
233 this.cacheJndiName = cacheJndiName;
234 }
235
236 /**
237 * Get the name in JNDI of a {@link CacheFactory} instance that should be used to create the cache for this source.
238 * <p>
239 * This source first attempts to find an existing cache in {@link #getCacheJndiName() JNDI}. If none is found, then it
240 * attempts to create a cache instance using the {@link CacheFactory} found in {@link #getCacheFactoryJndiName() JNDI} (or the
241 * {@link DefaultCacheFactory} if no such factory is available) and the {@link #getCacheConfigurationName() cache
242 * configuration name} if supplied or the default configuration if not set.
243 * </p>
244 *
245 * @return the JNDI name of the {@link CacheFactory} instance that should be used, or null if the {@link DefaultCacheFactory}
246 * should be used if a cache is to be created
247 * @see #setCacheFactoryJndiName(String)
248 * @see #getCacheConfigurationName()
249 * @see #getCacheJndiName()
250 */
251 public String getCacheFactoryJndiName() {
252 return cacheFactoryJndiName;
253 }
254
255 /**
256 * Set the name in JNDI of a {@link CacheFactory} instance that should be used to obtain the {@link Cache} instance used by
257 * this source.
258 * <p>
259 * This source first attempts to find an existing cache in {@link #getCacheJndiName() JNDI}. If none is found, then it
260 * attempts to create a cache instance using the {@link CacheFactory} found in {@link #getCacheFactoryJndiName() JNDI} (or the
261 * {@link DefaultCacheFactory} if no such factory is available) and the {@link #getCacheConfigurationName() cache
262 * configuration name} if supplied or the default configuration if not set.
263 * </p>
264 *
265 * @param jndiName the JNDI name of the {@link CacheFactory} instance that should be used, or null if the
266 * {@link DefaultCacheFactory} should be used if a cache is to be created
267 * @see #setCacheFactoryJndiName(String)
268 * @see #getCacheConfigurationName()
269 * @see #getCacheJndiName()
270 */
271 public synchronized void setCacheFactoryJndiName( String jndiName ) {
272 if (this.cacheFactoryJndiName == jndiName || this.cacheFactoryJndiName != null
273 && this.cacheFactoryJndiName.equals(jndiName)) return; // unchanged
274 this.cacheFactoryJndiName = jndiName;
275 }
276
277 /**
278 * Get the name of the configuration that should be used if a {@link Cache cache} is to be created using the
279 * {@link CacheFactory} found in JNDI or the {@link DefaultCacheFactory} if needed.
280 * <p>
281 * This source first attempts to find an existing cache in {@link #getCacheJndiName() JNDI}. If none is found, then it
282 * attempts to create a cache instance using the {@link CacheFactory} found in {@link #getCacheFactoryJndiName() JNDI} (or the
283 * {@link DefaultCacheFactory} if no such factory is available) and the {@link #getCacheConfigurationName() cache
284 * configuration name} if supplied or the default configuration if not set.
285 * </p>
286 *
287 * @return the name of the configuration that should be passed to the {@link CacheFactory}, or null if the default
288 * configuration should be used
289 * @see #setCacheConfigurationName(String)
290 * @see #getCacheFactoryJndiName()
291 * @see #getCacheJndiName()
292 */
293 public String getCacheConfigurationName() {
294 return cacheConfigurationName;
295 }
296
297 /**
298 * Get the name of the configuration that should be used if a {@link Cache cache} is to be created using the
299 * {@link CacheFactory} found in JNDI or the {@link DefaultCacheFactory} if needed.
300 * <p>
301 * This source first attempts to find an existing cache in {@link #getCacheJndiName() JNDI}. If none is found, then it
302 * attempts to create a cache instance using the {@link CacheFactory} found in {@link #getCacheFactoryJndiName() JNDI} (or the
303 * {@link DefaultCacheFactory} if no such factory is available) and the {@link #getCacheConfigurationName() cache
304 * configuration name} if supplied or the default configuration if not set.
305 * </p>
306 *
307 * @param cacheConfigurationName the name of the configuration that should be passed to the {@link CacheFactory}, or null if
308 * the default configuration should be used
309 * @see #getCacheConfigurationName()
310 * @see #getCacheFactoryJndiName()
311 * @see #getCacheJndiName()
312 */
313 public synchronized void setCacheConfigurationName( String cacheConfigurationName ) {
314 if (this.cacheConfigurationName == cacheConfigurationName || this.cacheConfigurationName != null
315 && this.cacheConfigurationName.equals(cacheConfigurationName)) return; // unchanged
316 this.cacheConfigurationName = cacheConfigurationName;
317 }
318
319 /**
320 * Get the UUID of the root node for the cache. If the cache exists, this UUID is not used but is instead set to the UUID of
321 * the existing root node.
322 *
323 * @return the UUID of the root node for the cache.
324 */
325 public String getRootNodeUuid() {
326 return this.rootNodeUuid.toString();
327 }
328
329 /**
330 * Get the UUID of the root node for the cache. If the cache exists, this UUID is not used but is instead set to the UUID of
331 * the existing root node.
332 *
333 * @return the UUID of the root node for the cache.
334 */
335 public UUID getRootNodeUuidObject() {
336 return this.rootNodeUuid;
337 }
338
339 /**
340 * Set the UUID of the root node in this repository. If the cache exists, this UUID is not used but is instead set to the UUID
341 * of the existing root node.
342 *
343 * @param rootNodeUuid the UUID of the root node for the cache, or null if the UUID should be randomly generated
344 */
345 public synchronized void setRootNodeUuid( String rootNodeUuid ) {
346 UUID uuid = null;
347 if (rootNodeUuid == null) uuid = UUID.randomUUID();
348 else uuid = UUID.fromString(rootNodeUuid);
349 if (this.rootNodeUuid.equals(uuid)) return; // unchanged
350 this.rootNodeUuid = uuid;
351 }
352
353 /**
354 * Get the name of the default workspace.
355 *
356 * @return the name of the workspace that should be used by default; never null
357 */
358 public String getNameOfDefaultWorkspace() {
359 return defaultWorkspace;
360 }
361
362 /**
363 * Set the name of the workspace that should be used when clients don't specify a workspace.
364 *
365 * @param nameOfDefaultWorkspace the name of the workspace that should be used by default, or null if the
366 * {@link #DEFAULT_NAME_OF_DEFAULT_WORKSPACE default name} should be used
367 */
368 public synchronized void setNameOfDefaultWorkspace( String nameOfDefaultWorkspace ) {
369 this.defaultWorkspace = nameOfDefaultWorkspace != null ? nameOfDefaultWorkspace : DEFAULT_NAME_OF_DEFAULT_WORKSPACE;
370 }
371
372 /**
373 * Gets the names of the workspaces that are available when this source is created.
374 *
375 * @return the names of the workspaces that this source starts with, or null if there are no such workspaces
376 * @see #setPredefinedWorkspaceNames(String[])
377 * @see #setCreatingWorkspacesAllowed(boolean)
378 */
379 public synchronized String[] getPredefinedWorkspaceNames() {
380 String[] copy = new String[predefinedWorkspaces.length];
381 System.arraycopy(predefinedWorkspaces, 0, copy, 0, predefinedWorkspaces.length);
382 return copy;
383 }
384
385 /**
386 * Sets the names of the workspaces that are available when this source is created.
387 *
388 * @param predefinedWorkspaceNames the names of the workspaces that this source should start with, or null if there are no
389 * such workspaces
390 * @see #setCreatingWorkspacesAllowed(boolean)
391 * @see #getPredefinedWorkspaceNames()
392 */
393 public synchronized void setPredefinedWorkspaceNames( String[] predefinedWorkspaceNames ) {
394 this.predefinedWorkspaces = predefinedWorkspaceNames;
395 }
396
397 /**
398 * Get whether this source allows workspaces to be created dynamically.
399 *
400 * @return true if this source allows workspaces to be created by clients, or false if the
401 * {@link #getPredefinedWorkspaceNames() set of workspaces} is fixed
402 * @see #setPredefinedWorkspaceNames(String[])
403 * @see #getPredefinedWorkspaceNames()
404 * @see #setCreatingWorkspacesAllowed(boolean)
405 */
406 public boolean isCreatingWorkspacesAllowed() {
407 return capabilities.supportsCreatingWorkspaces();
408 }
409
410 /**
411 * Set whether this source allows workspaces to be created dynamically.
412 *
413 * @param allowWorkspaceCreation true if this source allows workspaces to be created by clients, or false if the
414 * {@link #getPredefinedWorkspaceNames() set of workspaces} is fixed
415 * @see #setPredefinedWorkspaceNames(String[])
416 * @see #getPredefinedWorkspaceNames()
417 * @see #isCreatingWorkspacesAllowed()
418 */
419 public synchronized void setCreatingWorkspacesAllowed( boolean allowWorkspaceCreation ) {
420 capabilities = new RepositorySourceCapabilities(true, capabilities.supportsUpdates(), false, allowWorkspaceCreation,
421 capabilities.supportsReferences());
422 }
423
424 /**
425 * {@inheritDoc}
426 *
427 * @see org.jboss.dna.graph.connector.RepositorySource#getConnection()
428 */
429 @SuppressWarnings( "unchecked" )
430 public synchronized RepositoryConnection getConnection() throws RepositorySourceException {
431 if (getName() == null) {
432 I18n msg = JBossCacheConnectorI18n.propertyIsRequired;
433 throw new RepositorySourceException(getName(), msg.text("name"));
434 }
435 if (this.workspaces == null) {
436 Context context = getContext();
437 if (context == null) {
438 try {
439 context = new InitialContext();
440 } catch (NamingException err) {
441 throw new RepositorySourceException(name, err);
442 }
443 }
444
445 // Look for a cache factory in JNDI ...
446 CacheFactory<Name, Object> cacheFactory = null;
447 String jndiName = getCacheFactoryJndiName();
448 if (jndiName != null && jndiName.trim().length() != 0) {
449 Object object = null;
450 try {
451 object = context.lookup(jndiName);
452 if (object != null) cacheFactory = (CacheFactory<Name, Object>)object;
453 } catch (ClassCastException err) {
454 I18n msg = JBossCacheConnectorI18n.objectFoundInJndiWasNotCacheFactory;
455 String className = object != null ? object.getClass().getName() : "null";
456 throw new RepositorySourceException(getName(), msg.text(jndiName, this.getName(), className), err);
457 } catch (Throwable err) {
458 if (err instanceof RuntimeException) throw (RuntimeException)err;
459 throw new RepositorySourceException(getName(), err);
460 }
461 }
462 if (cacheFactory == null) cacheFactory = new DefaultCacheFactory<Name, Object>();
463
464 // Get the default cache configuration name
465 String configName = this.getCacheConfigurationName();
466
467 // Create the set of initial names ...
468 Set<String> initialNames = new HashSet<String>();
469 for (String initialName : getPredefinedWorkspaceNames())
470 initialNames.add(initialName);
471
472 // Now create the workspace manager ...
473 this.workspaces = new JBossCacheWorkspaces(getName(), cacheFactory, configName, initialNames, context);
474 }
475
476 return new JBossCacheConnection(this, this.workspaces);
477 }
478
479 protected Context getContext() {
480 return this.jndiContext;
481 }
482
483 protected synchronized void setContext( Context context ) {
484 this.jndiContext = context;
485 }
486
487 /**
488 * {@inheritDoc}
489 */
490 @Override
491 public boolean equals( Object obj ) {
492 if (obj == this) return true;
493 if (obj instanceof JBossCacheSource) {
494 JBossCacheSource that = (JBossCacheSource)obj;
495 if (this.getName() == null) {
496 if (that.getName() != null) return false;
497 } else {
498 if (!this.getName().equals(that.getName())) return false;
499 }
500 return true;
501 }
502 return false;
503 }
504
505 /**
506 * {@inheritDoc}
507 */
508 public synchronized Reference getReference() {
509 String className = getClass().getName();
510 String factoryClassName = this.getClass().getName();
511 Reference ref = new Reference(className, factoryClassName, null);
512
513 ref.add(new StringRefAddr(SOURCE_NAME, getName()));
514 ref.add(new StringRefAddr(ROOT_NODE_UUID, getRootNodeUuid().toString()));
515 ref.add(new StringRefAddr(CACHE_JNDI_NAME, getCacheJndiName()));
516 ref.add(new StringRefAddr(CACHE_FACTORY_JNDI_NAME, getCacheFactoryJndiName()));
517 ref.add(new StringRefAddr(CACHE_CONFIGURATION_NAME, getCacheConfigurationName()));
518 ref.add(new StringRefAddr(RETRY_LIMIT, Integer.toString(getRetryLimit())));
519 ref.add(new StringRefAddr(DEFAULT_WORKSPACE, getNameOfDefaultWorkspace()));
520 ref.add(new StringRefAddr(ALLOW_CREATING_WORKSPACES, Boolean.toString(isCreatingWorkspacesAllowed())));
521 String[] workspaceNames = getPredefinedWorkspaceNames();
522 if (workspaceNames != null && workspaceNames.length != 0) {
523 ref.add(new StringRefAddr(PREDEFINED_WORKSPACE_NAMES, StringUtil.combineLines(workspaceNames)));
524 }
525 if (getDefaultCachePolicy() != null) {
526 ByteArrayOutputStream baos = new ByteArrayOutputStream();
527 CachePolicy policy = getDefaultCachePolicy();
528 try {
529 ObjectOutputStream oos = new ObjectOutputStream(baos);
530 oos.writeObject(policy);
531 ref.add(new BinaryRefAddr(DEFAULT_CACHE_POLICY, baos.toByteArray()));
532 } catch (IOException e) {
533 I18n msg = JBossCacheConnectorI18n.errorSerializingCachePolicyInSource;
534 throw new RepositorySourceException(getName(), msg.text(policy.getClass().getName(), getName()), e);
535 }
536 }
537 return ref;
538 }
539
540 /**
541 * {@inheritDoc}
542 */
543 public Object getObjectInstance( Object obj,
544 javax.naming.Name name,
545 Context nameCtx,
546 Hashtable<?, ?> environment ) throws Exception {
547 if (obj instanceof Reference) {
548 Map<String, Object> values = new HashMap<String, Object>();
549 Reference ref = (Reference)obj;
550 Enumeration<?> en = ref.getAll();
551 while (en.hasMoreElements()) {
552 RefAddr subref = (RefAddr)en.nextElement();
553 if (subref instanceof StringRefAddr) {
554 String key = subref.getType();
555 Object value = subref.getContent();
556 if (value != null) values.put(key, value.toString());
557 } else if (subref instanceof BinaryRefAddr) {
558 String key = subref.getType();
559 Object value = subref.getContent();
560 if (value instanceof byte[]) {
561 // Deserialize ...
562 ByteArrayInputStream bais = new ByteArrayInputStream((byte[])value);
563 ObjectInputStream ois = new ObjectInputStream(bais);
564 value = ois.readObject();
565 values.put(key, value);
566 }
567 }
568 }
569 String sourceName = (String)values.get(SOURCE_NAME);
570 String rootNodeUuidString = (String)values.get(ROOT_NODE_UUID);
571 String cacheJndiName = (String)values.get(CACHE_JNDI_NAME);
572 String cacheFactoryJndiName = (String)values.get(CACHE_FACTORY_JNDI_NAME);
573 String cacheConfigurationName = (String)values.get(CACHE_CONFIGURATION_NAME);
574 Object defaultCachePolicy = values.get(DEFAULT_CACHE_POLICY);
575 String retryLimit = (String)values.get(RETRY_LIMIT);
576 String defaultWorkspace = (String)values.get(DEFAULT_WORKSPACE);
577 String createWorkspaces = (String)values.get(ALLOW_CREATING_WORKSPACES);
578
579 String combinedWorkspaceNames = (String)values.get(PREDEFINED_WORKSPACE_NAMES);
580 String[] workspaceNames = null;
581 if (combinedWorkspaceNames != null) {
582 List<String> paths = StringUtil.splitLines(combinedWorkspaceNames);
583 workspaceNames = paths.toArray(new String[paths.size()]);
584 }
585
586 // Create the source instance ...
587 JBossCacheSource source = new JBossCacheSource();
588 if (sourceName != null) source.setName(sourceName);
589 if (rootNodeUuidString != null) source.setRootNodeUuid(rootNodeUuidString);
590 if (cacheJndiName != null) source.setCacheJndiName(cacheJndiName);
591 if (cacheFactoryJndiName != null) source.setCacheFactoryJndiName(cacheFactoryJndiName);
592 if (cacheConfigurationName != null) source.setCacheConfigurationName(cacheConfigurationName);
593 if (defaultCachePolicy instanceof CachePolicy) {
594 source.setDefaultCachePolicy((CachePolicy)defaultCachePolicy);
595 }
596 if (retryLimit != null) source.setRetryLimit(Integer.parseInt(retryLimit));
597 if (defaultWorkspace != null) source.setNameOfDefaultWorkspace(defaultWorkspace);
598 if (createWorkspaces != null) source.setCreatingWorkspacesAllowed(Boolean.parseBoolean(createWorkspaces));
599 if (workspaceNames != null && workspaceNames.length != 0) source.setPredefinedWorkspaceNames(workspaceNames);
600 return source;
601 }
602 return null;
603 }
604 }