Author: rhauch
Date: 2009-04-23 12:43:27 -0400 (Thu, 23 Apr 2009)
New Revision: 849
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaLexicon.java
Modified:
trunk/dna-common/src/main/java/org/jboss/dna/common/util/Reflection.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/DnaLexicon.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryI18n.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleSessionFactory.java
trunk/dna-repository/src/main/resources/org/jboss/dna/repository/RepositoryI18n.properties
trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaConfigurationTest.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaEngineTest.java
Log:
DNA-58 Create repository configuration and component
Refactored the DnaConfiguration to make use of the graph repository for storing the
configuration. When used, the DnaConfiguration instance persists all the information to
this graph, where it can be read and used. A "save()" method was added to allow
the code using the DnaConfiguration instance to control when the content is updated.
(This also simplified the unit testing, since it's very easy to check the graph
content after the DnaConfiguration methods are used.) The DnaEngine was then updated to
read the configuration repository content and to instantiate and set up the services.
This "configuration repository" defaults to an in-memory repository, but can be
set up to use a particular RepositorySource instance (that has already been set up) or to
reflectively create an instance given the class name, optional class loader, and various
(implementation-specific) Java bean properties.
This means that in the simplest case, one can simply create a DnaConfiguration and
configure the sequencers, sources, detectors, etc. It also makes it very simple to
"read" an XML file with the configuration, since that just uses the XML graph
importer. But using a configuration repository shines in the more advanced cases, such as
when a process participates in a cluster. Here, the process can create a
DnaConfiguration, very easily set it up to use a shared (and remote) configuration
repository (that already has the content), and without any other work immediately build
the DnaEngine.
Using a graph as the configuration repository also means that any changes to the
configuration could be monitored via graph events, allowing the DnaEngine to monitor any
changes and dynamically alter its services.
Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/util/Reflection.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/util/Reflection.java 2009-04-23
16:29:28 UTC (rev 848)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/util/Reflection.java 2009-04-23
16:43:27 UTC (rev 849)
@@ -234,7 +234,7 @@
}
/**
- * Find the method on the target class that matches the supplied method name.
+ * Find the methods on the target class that matches the supplied method name.
*
* @param methodNamePattern the regular expression pattern for the name of the method
that is to be found.
* @return the Method objects that have a matching name, or an empty array if there
are no methods that have a matching name.
@@ -252,6 +252,50 @@
}
/**
+ * Find the getter methods on the target class that begin with "get" or
"is", that have no parameters, and that return
+ * something other than void. This method skips the {@link Object#getClass()}
method.
+ *
+ * @return the Method objects for the getters; never null but possibly empty
+ */
+ public Method[] findGetterMethods() {
+ final Method[] allMethods = this.targetClass.getMethods();
+ final List<Method> result = new ArrayList<Method>();
+ for (int i = 0; i < allMethods.length; i++) {
+ final Method m = allMethods[i];
+ int numParams = m.getParameterTypes().length;
+ if (numParams != 0) continue;
+ String name = m.getName();
+ if (name.equals("getClass")) continue;
+ if (m.getReturnType() == Void.TYPE) continue;
+ if (name.startsWith("get") || name.startsWith("is")) {
+ result.add(m);
+ }
+ }
+ return result.toArray(new Method[result.size()]);
+ }
+
+ /**
+ * Find the property names with getter methods on the target class. This method
returns the property names for the methods
+ * returned by {@link #findGetterMethods()}.
+ *
+ * @return the Java Bean property names for the getters; never null but possibly
empty
+ */
+ public String[] findGetterPropertyNames() {
+ final Method[] getters = findGetterMethods();
+ final List<String> result = new ArrayList<String>();
+ for (int i = 0; i < getters.length; i++) {
+ final Method m = getters[i];
+ String name = m.getName();
+ if (name.startsWith("get") && name.length() > 3) {
+ result.add(name.substring(3));
+ } else if (name.startsWith("is") && name.length() > 2)
{
+ result.add(name.substring(2));
+ }
+ }
+ return result.toArray(new String[result.size()]);
+ }
+
+ /**
* Find the method on the target class that matches the supplied method name.
*
* @param methodName the name of the method that is to be found.
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/DnaLexicon.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/DnaLexicon.java 2009-04-23 16:29:28 UTC
(rev 848)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/DnaLexicon.java 2009-04-23 16:43:27 UTC
(rev 849)
@@ -29,7 +29,7 @@
/**
* @author Randall Hauch
*/
-public class DnaLexicon extends org.jboss.dna.graph.DnaLexicon {
+public class DnaLexicon extends org.jboss.dna.repository.DnaLexicon {
public static final Name DEFINED = new BasicName(Namespace.URI,
"defined");
public static final Name NAMESPACE = new BasicName(Namespace.URI,
"namespace");
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java 2009-04-23
16:29:28 UTC (rev 848)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java 2009-04-23
16:43:27 UTC (rev 849)
@@ -21,45 +21,61 @@
*/
package org.jboss.dna.repository;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import net.jcip.annotations.Immutable;
import org.jboss.dna.common.component.ClassLoaderFactory;
import org.jboss.dna.common.i18n.I18n;
+import org.jboss.dna.common.text.Inflector;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.common.util.Reflection;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.Node;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
import org.jboss.dna.graph.mimetype.MimeTypeDetector;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.PathExpression;
-import org.jboss.dna.graph.sequencer.StreamSequencer;
-import org.jboss.dna.repository.mimetype.MimeTypeDetectorConfig;
+import org.jboss.dna.graph.property.PathFactory;
+import org.jboss.dna.graph.property.ValueFormatException;
import org.jboss.dna.repository.sequencer.Sequencer;
-import org.jboss.dna.repository.sequencer.SequencerConfig;
-import org.jboss.dna.repository.sequencer.StreamSequencerAdapter;
/**
*/
@Immutable
public class DnaConfiguration {
- protected RepositorySource configurationSource;
- protected String configurationSourceDescription;
- protected Graph configuration;
+ protected static final Map<String, Name> NAMES_TO_MAP;
+ static {
+ Map<String, Name> names = new HashMap<String, Name>();
+ names.put(DnaLexicon.READABLE_NAME.getLocalName(), DnaLexicon.READABLE_NAME);
+ names.put(DnaLexicon.DESCRIPTION.getLocalName(), DnaLexicon.DESCRIPTION);
+ names.put(DnaLexicon.DEFAULT_CACHE_POLICY.getLocalName(),
DnaLexicon.DEFAULT_CACHE_POLICY);
+ names.put(DnaLexicon.RETRY_LIMIT.getLocalName(), DnaLexicon.RETRY_LIMIT);
+ names.put(DnaLexicon.PATH_EXPRESSIONS.getLocalName(),
DnaLexicon.PATH_EXPRESSIONS);
+ names.put(DnaLexicon.CLASSNAME.getLocalName(), DnaLexicon.CLASSNAME);
+ names.put(DnaLexicon.CLASSPATH.getLocalName(), DnaLexicon.CLASSPATH);
+ NAMES_TO_MAP = Collections.unmodifiableMap(names);
+ }
+
+ protected class Source {
+ protected RepositorySource source;
+ protected String description;
+ protected Path path;
+ }
+
private final ExecutionContext context;
+ protected Source configurationSource;
+ private Path sourcesPath;
+ private Path sequencersPath;
+ private Path detectorsPath;
+ private Graph graph;
+ private Graph.Batch batch;
/**
- * Mapping of repository names to configured repositories
- */
- protected final Map<String, DnaRepositoryDetails> repositories;
- protected final Map<String, DnaMimeTypeDetectorDetails> mimeTypeDetectors;
- protected final Map<String, DnaSequencerDetails> sequencers;
-
- /**
* Create a new configuration for DNA.
*/
public DnaConfiguration() {
@@ -70,61 +86,79 @@
* Specify a new {@link ExecutionContext} that should be used for this DNA instance.
*
* @param context the new context, or null if a default-constructed execution context
should be used
+ * @throws IllegalArgumentException if the supplied context reference is null
*/
public DnaConfiguration( ExecutionContext context ) {
+ CheckArg.isNotNull(context, "context");
this.context = context;
- this.repositories = new HashMap<String, DnaRepositoryDetails>();
- this.mimeTypeDetectors = new HashMap<String,
DnaMimeTypeDetectorDetails>();
- this.sequencers = new HashMap<String, DnaSequencerDetails>();
// Set up the default configuration repository ...
this.configurationSource = createDefaultConfigurationSource();
+ }
+ /**
+ * Method that is used to set up the default configuration repository source. By
default, this method sets up the
+ * {@link InMemoryRepositorySource} loaded from the classpath.
+ *
+ * @return the default repository source
+ */
+ protected Source createDefaultConfigurationSource() {
+ InMemoryRepositorySource defaultSource = new InMemoryRepositorySource();
+ defaultSource.setName("Configuration");
+ Source result = new Source();
+ result.source = defaultSource;
+ result.path =
this.context.getValueFactories().getPathFactory().createRootPath();
+ result.description = "Configuration Repository";
+ return result;
}
- private DnaConfiguration( DnaConfiguration source ) {
- this.configuration = source.configuration;
- this.configurationSource = source.configurationSource;
- this.context = source.context;
- this.configurationSourceDescription = source.configurationSourceDescription;
- this.repositories = new HashMap<String,
DnaRepositoryDetails>(source.repositories);
- this.mimeTypeDetectors = new HashMap<String,
DnaMimeTypeDetectorDetails>(source.mimeTypeDetectors);
- this.sequencers = new HashMap<String,
DnaSequencerDetails>(source.sequencers);
+ protected final ExecutionContext context() {
+ return this.context;
}
- private DnaConfiguration with( String repositoryName,
- DnaRepositoryDetails details ) {
- DnaConfiguration newConfig = new DnaConfiguration(this);
- newConfig.repositories.put(repositoryName, details);
-
- return newConfig;
+ protected final PathFactory pathFactory() {
+ return context().getValueFactories().getPathFactory();
}
- protected ExecutionContext getExecutionContext() {
- return this.context;
+ /**
+ * Get the graph containing the configuration information. This should be called only
after the
+ * {@link #withConfigurationRepository() configuration repository} is set up.
+ *
+ * @return the configuration repository graph; never null
+ * @see #graph()
+ */
+ protected final Graph graph() {
+ if (this.graph == null) {
+ this.graph = Graph.create(configurationSource.source, context);
+ }
+ return this.graph;
}
- protected Graph getConfiguration() {
- if (this.configuration == null) {
- this.configuration = Graph.create(configurationSource, context);
+ /**
+ * Get the graph batch that can be used to change the configuration, where the
changes are enqueued until {@link #save()
+ * saved}. This should be called only after the {@link #withConfigurationRepository()
configuration repository} is set up.
+ *
+ * @return the latest batch for changes to the configuration repository; never null
+ * @see #graph()
+ */
+ protected final Graph.Batch configuration() {
+ if (this.batch == null) {
+ this.batch = graph().batch();
}
- return this.configuration;
+ return this.batch;
}
/**
- * Method that is used to set up the default configuration repository source. By
default, this method sets up the
- * {@link InMemoryRepositorySource} loaded from the classpath.
+ * Save any changes that have been made so far to the configuration. This method does
nothing if no changes have been made.
*
- * @return the default repository source
+ * @return this configuration object for method chaining purposes; never null
*/
- protected RepositorySource createDefaultConfigurationSource() {
- this.withConfigurationRepository()
- .usingClass(InMemoryRepositorySource.class.getName())
- .loadedFromClasspath()
- .describedAs("Configuration Repository")
- .with("name")
- .setTo("Configuration");
- return configurationSource;
+ public DnaConfiguration save() {
+ if (this.batch != null) {
+ this.batch.execute();
+ this.batch = this.graph.batch();
+ }
+ return this;
}
/**
@@ -135,40 +169,69 @@
* @return the interface for choosing the class, which returns the interface used to
configure the repository source that will
* be used for the configuration repository; never null
*/
- public ChooseClass<RepositorySource, RepositoryDetails>
withConfigurationRepository() {
- return addRepository(DnaEngine.CONFIGURATION_REPOSITORY_NAME);
+ public ChooseClass<RepositorySource, ConfigRepositoryDetails>
withConfigurationRepository() {
+ final Source source = this.configurationSource;
+ // The config repository is different, since it has to load immediately ...
+ return new ChooseClass<RepositorySource, ConfigRepositoryDetails>() {
+ public LoadedFrom<ConfigRepositoryDetails> usingClass( final String
className ) {
+ return new LoadedFrom<ConfigRepositoryDetails>() {
+ @SuppressWarnings( "unchecked" )
+ public ConfigRepositoryDetails loadedFrom( String... classpath ) {
+ ClassLoader classLoader = context().getClassLoader(classpath);
+ Class<? extends RepositorySource> clazz = null;
+ try {
+ clazz = (Class<? extends
RepositorySource>)classLoader.loadClass(className);
+ } catch (ClassNotFoundException err) {
+ throw new
DnaConfigurationException(RepositoryI18n.unableToLoadClassUsingClasspath.text(className,
+
classpath));
+ }
+ return usingClass(clazz);
+ }
+
+ @SuppressWarnings( "unchecked" )
+ public ConfigRepositoryDetails loadedFromClasspath() {
+ Class<? extends RepositorySource> clazz = null;
+ try {
+ clazz = (Class<? extends
RepositorySource>)Class.forName(className);
+ } catch (ClassNotFoundException err) {
+ throw new
DnaConfigurationException(RepositoryI18n.unableToLoadClass.text(className));
+ }
+ return usingClass(clazz);
+ }
+ };
+ }
+
+ public ConfigRepositoryDetails usingClass( Class<? extends
RepositorySource> repositorySource ) {
+ try {
+ source.source = repositorySource.newInstance();
+ } catch (InstantiationException err) {
+ I18n msg = RepositoryI18n.errorCreatingInstanceOfClass;
+ throw new
DnaConfigurationException(msg.text(repositorySource.getName(), err.getLocalizedMessage()),
err);
+ } catch (IllegalAccessException err) {
+ I18n msg = RepositoryI18n.errorCreatingInstanceOfClass;
+ throw new
DnaConfigurationException(msg.text(repositorySource.getName(), err.getLocalizedMessage()),
err);
+ }
+ return new ConfigurationSourceDetails();
+ }
+ };
}
/**
* Add a new {@link RepositorySource repository} for this configuration. The new
repository will have the supplied name, and
* if the name of an existing repository is used, this will replace the existing
repository configuration.
*
- * @param name the name of the new repository that is to be added
+ * @param id the id of the new repository that is to be added
* @return the interface for choosing the class, which returns the interface used to
configure the repository source; never
* null
* @throws IllegalArgumentException if the repository name is null, empty, or
otherwise invalid
* @see #addRepository(RepositorySource)
*/
- public ChooseClass<RepositorySource, RepositoryDetails> addRepository( final
String name ) {
- return new ClassChooser<RepositorySource, RepositoryDetails>() {
-
- @Override
- protected RepositoryDetails getComponentBuilder( String className,
- String... classpath ) {
- try {
- Class<?> clazz = Class.forName(className);
- Object newInstance = clazz.newInstance();
- assert newInstance instanceof RepositorySource;
-
- DnaRepositoryDetails details = new
DnaRepositoryDetails((RepositorySource)newInstance);
- DnaConfiguration.this.repositories.put(name, details);
-
- return details;
- } catch (Exception ex) {
- throw new DnaConfigurationException(ex);
- }
- }
- };
+ public ChooseClass<RepositorySource, RepositoryDetails> addRepository( final
String id ) {
+ CheckArg.isNotEmpty(id, "id");
+ // Now create the "dna:source" node with the supplied id ...
+ Path sourcePath = pathFactory().create(sourcesPath(), id);
+ configuration().create(sourcePath).with(DnaLexicon.READABLE_NAME, id).and();
+ return new ClassChooser<RepositorySource, RepositoryDetails>(sourcePath,
new GraphRepositoryDetails(sourcePath));
}
/**
@@ -181,338 +244,130 @@
* @see #addRepository(String)
*/
public DnaConfiguration addRepository( RepositorySource source ) {
- return this.with(source.getName(), new DnaRepositoryDetails(source));
+ CheckArg.isNotNull(source, "source");
+ CheckArg.isNotEmpty(source.getName(), "source.getName()");
+ String name = source.getName();
+ RepositoryDetails details =
addRepository(source.getName()).usingClass(source.getClass().getName()).loadedFromClasspath();
+ // Record all of the bean properties ...
+ Path sourcePath = pathFactory().create(sourcesPath(), name);
+ Reflection reflector = new Reflection(source.getClass());
+ for (String propertyName : reflector.findGetterPropertyNames()) {
+ Object value;
+ try {
+ value = reflector.invokeGetterMethodOnTarget(propertyName, source);
+ if (value == null) continue;
+ propertyName = Inflector.getInstance().lowerCamelCase(propertyName);
+ if (NAMES_TO_MAP.containsKey(propertyName)) {
+
configuration().set(NAMES_TO_MAP.get(propertyName)).to(value).on(sourcePath);
+ } else {
+ configuration().set(propertyName).to(value).on(sourcePath);
+ }
+ } catch (ValueFormatException err) {
+ throw err;
+ } catch (Throwable err) {
+ // Unable to call getter and set property
+ }
+ }
+ return details.and();
}
/**
* Add a new {@link Sequencer sequencer} to this configuration. The new sequencer
will have the supplied name, and if the name
* of an existing sequencer is used, this will replace the existing sequencer
configuration.
*
- * @param name the name of the new sequencer
+ * @param id the identifier of the new sequencer
* @return the interface for choosing the class, which returns the interface used to
configure the sequencer; never null
* @throws IllegalArgumentException if the sequencer name is null, empty, or
otherwise invalid
*/
- public ChooseClass<Sequencer, SequencerDetails> addSequencer( final String name
) {
- return new ClassChooser<Sequencer, SequencerDetails>() {
-
- @Override
- protected SequencerDetails getComponentBuilder( String className,
- String... classpath ) {
- try {
- Class<?> clazz = Class.forName(className);
- Object newInstance = clazz.newInstance();
- assert newInstance instanceof Sequencer;
-
- DnaSequencerDetails details = new DnaSequencerDetails(name,
(Sequencer)newInstance, classpath);
- DnaConfiguration.this.sequencers.put(name, details);
-
- return details;
- } catch (Exception ex) {
- throw new DnaConfigurationException(ex);
- }
- }
- };
+ public ChooseClass<Sequencer, SequencerDetails> addSequencer( final String id )
{
+ CheckArg.isNotEmpty(id, "id");
+ // Now create the "dna:sequencer" node with the supplied id ...
+ Path sequencerPath = pathFactory().create(sequencersPath(), id);
+ configuration().create(sequencerPath).with(DnaLexicon.READABLE_NAME, id).and();
+ return new ClassChooser<Sequencer, SequencerDetails>(sequencerPath, new
GraphSequencerDetails(sequencerPath));
}
/**
- * Add a new {@link StreamSequencer sequencer} to this configuration. The new stream
sequencer will have the supplied name,
- * and if the name of an existing sequencer is used, this will replace the existing
sequencer configuration.
- *
- * @param name the name of the new sequencer
- * @return the interface for choosing the class, which returns the interface used to
configure the stream sequencer; never
- * null
- * @throws IllegalArgumentException if the sequencer name is null, empty, or
otherwise invalid
- */
- public ChooseClass<StreamSequencer, SequencerDetails> addStreamSequencer( final
String name ) {
- return new ClassChooser<StreamSequencer, SequencerDetails>() {
-
- @Override
- protected SequencerDetails getComponentBuilder( String className,
- String... classpath ) {
- try {
- Class<?> clazz = Class.forName(className);
- Object newInstance = clazz.newInstance();
- assert newInstance instanceof StreamSequencer;
-
- DnaSequencerDetails details = new DnaSequencerDetails(
- name,
- new
StreamSequencerAdapter((StreamSequencer)newInstance),
- classpath);
- DnaConfiguration.this.sequencers.put(name, details);
-
- return details;
- } catch (Exception ex) {
- throw new DnaConfigurationException(ex);
- }
- }
- };
- }
-
- /**
* Add a new {@link MimeTypeDetector MIME type detector} to this configuration. The
new detector will have the supplied name,
* and if the name of an existing detector is used, this will replace the existing
detector configuration.
*
- * @param name the name of the new detector
+ * @param id the id of the new detector
* @return the interface for choosing the class, which returns the interface used to
configure the detector; never null
* @throws IllegalArgumentException if the detector name is null, empty, or otherwise
invalid
*/
- public ChooseClass<MimeTypeDetector, MimeTypeDetectorDetails>
addMimeTypeDetector( final String name ) {
- return new ClassChooser<MimeTypeDetector, MimeTypeDetectorDetails>() {
-
- @Override
- protected MimeTypeDetectorDetails getComponentBuilder( String className,
- String... classpath )
{
- try {
- Class<?> clazz = Class.forName(className);
- Object newInstance = clazz.newInstance();
- assert newInstance instanceof MimeTypeDetector;
-
- DnaMimeTypeDetectorDetails details = new
DnaMimeTypeDetectorDetails(name, (MimeTypeDetector)newInstance,
-
classpath);
- DnaConfiguration.this.mimeTypeDetectors.put(name, details);
-
- return details;
- } catch (Exception ex) {
- throw new DnaConfigurationException(ex);
- }
- }
- };
+ public ChooseClass<MimeTypeDetector, MimeTypeDetectorDetails>
addMimeTypeDetector( final String id ) {
+ CheckArg.isNotEmpty(id, "id");
+ // Now create the "dna:sequencer" node with the supplied id ...
+ Path detectorPath = pathFactory().create(detectorsPath(), id);
+ configuration().create(detectorPath).with(DnaLexicon.READABLE_NAME, id).and();
+ return new ClassChooser<MimeTypeDetector,
MimeTypeDetectorDetails>(detectorPath,
+ new
GraphMimeTypeDetectorDetails(detectorPath));
}
/**
* Complete this configuration and create the corresponding engine.
*
* @return the new engine configured by this instance
+ * @throws DnaConfigurationException if the engine cannot be created from this
configuration.
*/
- public DnaEngine build() {
+ public DnaEngine build() throws DnaConfigurationException {
+ save();
return new DnaEngine(this);
}
- /**
- * Interface used to configure a {@link RepositorySource repository}.
- */
- public interface RepositoryDetails
- extends SetDescription<RepositoryDetails>,
SetProperties<RepositoryDetails>, ConfigurationBuilder {
-
- RepositorySource getRepositorySource();
+ protected Path sourcesPath() {
+ // Make sure the "dna:sources" node is there
+ if (sourcesPath == null) {
+ Path path = pathFactory().create(this.configurationSource.path,
DnaLexicon.SOURCES);
+ Node node = graph().createIfMissing(path).andReturn();
+ this.sourcesPath = node.getLocation().getPath();
+ }
+ return this.sourcesPath;
}
- /**
- * Local implementation of the {@link MimeTypeDetectorDetails} interface that tracks
all of the user-provided configuration
- * details.
- */
- protected class DnaMimeTypeDetectorDetails implements MimeTypeDetectorDetails {
- final MimeTypeDetector mimeTypeDetector;
- private String name;
- private String description;
- private Map<String, Object> properties;
- private String className;
- private String[] classpath;
-
- protected DnaMimeTypeDetectorDetails( String name,
- MimeTypeDetector mimeTypeDetector,
- String[] classpath ) {
- this.mimeTypeDetector = mimeTypeDetector;
- this.name = name;
- this.description = mimeTypeDetector.getClass().getName();
- this.properties = new HashMap<String, Object>();
- this.className = mimeTypeDetector.getClass().getName();
- this.classpath = classpath;
+ protected Path sequencersPath() {
+ // Make sure the "dna:sequencers" node is there
+ if (sequencersPath == null) {
+ Path path = pathFactory().create(this.configurationSource.path,
DnaLexicon.SEQUENCERS);
+ Node node = graph().createIfMissing(path).andReturn();
+ this.sequencersPath = node.getLocation().getPath();
}
+ return this.sequencersPath;
+ }
- public Map<String, Object> getProperties() {
- return properties;
+ protected Path detectorsPath() {
+ // Make sure the "dna:mimeTypeDetectors" node is there
+ if (detectorsPath == null) {
+ Path path = pathFactory().create(this.configurationSource.path,
DnaLexicon.MIME_TYPE_DETECTORS);
+ Node node = graph().createIfMissing(path).andReturn();
+ this.detectorsPath = node.getLocation().getPath();
}
-
- protected String getDescription() {
- return description;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.repository.DnaConfiguration.SetDescription#describedAs(java.lang.String)
- */
- public MimeTypeDetectorDetails describedAs( String description ) {
- this.description = description;
- return this;
- }
-
- public PropertySetter<MimeTypeDetectorDetails> with( final String
propertyName ) {
- return new MappingPropertySetter<MimeTypeDetectorDetails>(propertyName,
this);
- }
-
- public MimeTypeDetector getMimeTypeDetector() {
- return mimeTypeDetector;
- }
-
- MimeTypeDetectorConfig getMimeTypeDetectorConfig() {
- return new MimeTypeDetectorConfig(name, description, properties, className,
classpath);
- }
-
- public DnaConfiguration and() {
- return DnaConfiguration.this;
- }
-
+ return this.detectorsPath;
}
/**
- * Local implementation of the {@link RepositoryDetails} interface that tracks all of
the user-provided configuration details.
+ * Interface used to configure a {@link RepositorySource repository}.
*/
- protected class DnaRepositoryDetails implements RepositoryDetails {
- private final RepositorySource source;
- private final String description;
- private Map<String, Object> properties;
-
- protected DnaRepositoryDetails( RepositorySource source ) {
- this.source = source;
- this.description = source.getName();
- this.properties = new HashMap<String, Object>();
- }
-
- protected DnaRepositoryDetails( RepositorySource source,
- String description ) {
- this.source = source;
- this.description = description;
- }
-
- public Map<String, Object> getProperties() {
- return properties;
- }
-
- protected String getDescription() {
- return description;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.repository.DnaConfiguration.SetDescription#describedAs(java.lang.String)
- */
- public RepositoryDetails describedAs( String description ) {
- return new DnaRepositoryDetails(this.source, description);
- }
-
- public PropertySetter<RepositoryDetails> with( final String propertyName )
{
- return new BeanPropertySetter<RepositoryDetails>(source, propertyName,
this);
- }
-
- public RepositorySource getRepositorySource() {
- return source;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.repository.DnaConfiguration.ConfigurationBuilder#and()
- */
- public DnaConfiguration and() {
- return DnaConfiguration.this;
- }
+ public interface RepositoryDetails
+ extends SetName<RepositoryDetails>,
SetDescription<RepositoryDetails>, SetProperties<RepositoryDetails>,
+ ConfigurationBuilder {
}
- /**
- * Local implementation of the {@link SequencerDetails} interface that tracks all of
the user-provided configuration details.
- */
- protected class DnaSequencerDetails implements SequencerDetails {
- private final Sequencer sequencer;
- private String name;
- private String description;
- private Map<String, Object> properties;
- private String className;
- private String[] classpath;
- final List<PathExpression> sourcePathExpressions;
- final List<PathExpression> targetPathExpressions;
-
- protected DnaSequencerDetails( String name,
- Sequencer sequencer,
- String[] classpath ) {
- this.sequencer = sequencer;
- this.name = name;
- this.description = sequencer.getClass().getName();
- this.properties = new HashMap<String, Object>();
- this.className = sequencer.getClass().getName();
- this.classpath = classpath;
- this.sourcePathExpressions = new ArrayList<PathExpression>();
- this.targetPathExpressions = new ArrayList<PathExpression>();
- }
-
- public Map<String, Object> getProperties() {
- return properties;
- }
-
- protected String getDescription() {
- return description;
- }
-
+ public interface ConfigRepositoryDetails
+ extends SetDescription<ConfigRepositoryDetails>,
SetProperties<ConfigRepositoryDetails>, ConfigurationBuilder {
/**
- * {@inheritDoc}
+ * Specify the path under which the configuration content is to be found. This
path is assumed to be "/" by default.
*
- * @see
org.jboss.dna.repository.DnaConfiguration.SetDescription#describedAs(java.lang.String)
+ * @param path the path to the configuration content in the configuration source;
may not be null
+ * @return this instance for method chaining purposes; never null
*/
- public SequencerDetails describedAs( String description ) {
- this.description = description;
- return this;
- }
-
- public PropertySetter<SequencerDetails> with( final String propertyName )
{
- return new MappingPropertySetter<SequencerDetails>(propertyName,
this);
- }
-
- public Sequencer getSequencer() {
- return sequencer;
- }
-
- SequencerConfig getSequencerConfig() {
- return new SequencerConfig(this.name, this.description, this.properties,
this.className, this.classpath);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.repository.DnaConfiguration.ConfigurationBuilder#and()
- */
- public DnaConfiguration and() {
- return DnaConfiguration.this;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.repository.DnaConfiguration.SequencerDetails#sequencingFrom(java.lang.String)
- */
- public PathExpressionOutput sequencingFrom( String inputExpressionPath ) {
- return this.sequencingFrom(PathExpression.compile(inputExpressionPath));
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.repository.DnaConfiguration.SequencerDetails#sequencingFrom(org.jboss.dna.graph.property.PathExpression)
- */
- public PathExpressionOutput sequencingFrom( final PathExpression
inputExpressionPath ) {
- final DnaSequencerDetails details = this;
- return new PathExpressionOutput() {
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.repository.DnaConfiguration.PathExpressionOutput#andOutputtingTo(java.lang.String)
- */
- public DnaSequencerDetails andOutputtingTo( final String
outputExpressionPath ) {
- details.sourcePathExpressions.add(inputExpressionPath);
-
details.targetPathExpressions.add(PathExpression.compile(outputExpressionPath));
- return details;
- }
- };
- }
-
+ public ConfigRepositoryDetails under( String path );
}
/**
* Interface used to configure a {@link Sequencer sequencer}.
*/
- public interface SequencerDetails extends SetDescription<SequencerDetails>,
ConfigurationBuilder {
+ public interface SequencerDetails extends SetName<SequencerDetails>,
SetDescription<SequencerDetails>, ConfigurationBuilder {
/**
* Specify the input {@link PathExpression path expression} represented as a
string, which determines when this sequencer
@@ -529,9 +384,9 @@
*
* @param inputPathExpression the path expression for nodes that, when they
change, will be passed as an input to the
* sequencer
- * @return the interface used to specify the output path expression; never null
+ * @return the interface used to continue specifying the configuration of the
sequencer
*/
- PathExpressionOutput sequencingFrom( PathExpression inputPathExpression );
+ SequencerDetails sequencingFrom( PathExpression inputPathExpression );
}
/**
@@ -553,7 +408,8 @@
* Interface used to configure a {@link MimeTypeDetector MIME type detector}.
*/
public interface MimeTypeDetectorDetails
- extends SetDescription<MimeTypeDetectorDetails>,
SetProperties<MimeTypeDetectorDetails>, ConfigurationBuilder {
+ extends SetName<MimeTypeDetectorDetails>,
SetDescription<MimeTypeDetectorDetails>,
+ SetProperties<MimeTypeDetectorDetails>, ConfigurationBuilder {
}
/**
@@ -670,6 +526,7 @@
*
* @param clazz the class that should be instantiated
* @return the next component to continue configuration; never null
+ * @throws DnaConfigurationException if the class could not be accessed and
instantiated (if needed)
* @throws IllegalArgumentException if the class reference is null
*/
ReturnType usingClass( Class<? extends ComponentClassType> clazz );
@@ -691,6 +548,21 @@
}
/**
+ * The interface used to set a human readable name on a component.
+ *
+ * @param <ReturnType> the interface returned from these methods
+ */
+ public interface SetName<ReturnType> {
+ /**
+ * Specify the human-readable name for this component.
+ *
+ * @param description the description; may be null or empty
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType named( String description );
+ }
+
+ /**
* Interface for specifying from where the component's class is to be loaded.
*
* @param <ReturnType> the interface returned from these methods
@@ -725,8 +597,6 @@
*/
public interface ConfigurationBuilder {
- Map<String, Object> getProperties();
-
/**
* Return a reference to the enclosing configuration so that it can be built or
further configured.
*
@@ -735,6 +605,211 @@
DnaConfiguration and();
}
+ protected class ConfigurationSourceDetails implements ConfigRepositoryDetails {
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetDescription#describedAs(java.lang.String)
+ */
+ public ConfigRepositoryDetails describedAs( String description ) {
+ DnaConfiguration.this.configurationSource.description = description;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetProperties#with(java.lang.String)
+ */
+ public PropertySetter<ConfigRepositoryDetails> with( String propertyName )
{
+ return new
BeanPropertySetter<ConfigRepositoryDetails>(DnaConfiguration.this.configurationSource.source,
+ propertyName, this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.ConfigRepositoryDetails#under(java.lang.String)
+ */
+ public ConfigRepositoryDetails under( String path ) {
+ CheckArg.isNotNull(path, "path");
+ DnaConfiguration.this.configurationSource.path =
context().getValueFactories().getPathFactory().create(path);
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.DnaConfiguration.ConfigurationBuilder#and()
+ */
+ public DnaConfiguration and() {
+ return DnaConfiguration.this;
+ }
+ }
+
+ protected class GraphRepositoryDetails implements RepositoryDetails {
+ private final Path path;
+
+ protected GraphRepositoryDetails( Path path ) {
+ assert path != null;
+ this.path = path;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetName#named(java.lang.String)
+ */
+ public RepositoryDetails named( String name ) {
+ configuration().set(DnaLexicon.READABLE_NAME).to(name).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetDescription#describedAs(java.lang.String)
+ */
+ public RepositoryDetails describedAs( String description ) {
+ configuration().set(DnaLexicon.DESCRIPTION).to(description).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetProperties#with(java.lang.String)
+ */
+ public PropertySetter<RepositoryDetails> with( String propertyName ) {
+ return new GraphPropertySetter<RepositoryDetails>(path, propertyName,
this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.DnaConfiguration.ConfigurationBuilder#and()
+ */
+ public DnaConfiguration and() {
+ return DnaConfiguration.this;
+ }
+ }
+
+ protected class GraphSequencerDetails implements SequencerDetails {
+ private final Path path;
+
+ protected GraphSequencerDetails( Path path ) {
+ assert path != null;
+ this.path = path;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SequencerDetails#sequencingFrom(java.lang.String)
+ */
+ public PathExpressionOutput sequencingFrom( final String from ) {
+ CheckArg.isNotEmpty(from, "from");
+ return new PathExpressionOutput() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.PathExpressionOutput#andOutputtingTo(java.lang.String)
+ */
+ public SequencerDetails andOutputtingTo( String into ) {
+ CheckArg.isNotEmpty(into, "into");
+ return sequencingFrom(PathExpression.compile(from + " =>
" + into));
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetName#named(java.lang.String)
+ */
+ public SequencerDetails named( String name ) {
+ configuration().set(DnaLexicon.READABLE_NAME).to(name).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SequencerDetails#sequencingFrom(org.jboss.dna.graph.property.PathExpression)
+ */
+ public SequencerDetails sequencingFrom( PathExpression expression ) {
+ CheckArg.isNotNull(expression, "expression");
+
configuration().set(DnaLexicon.PATH_EXPRESSIONS).on(path).to(expression.getExpression());
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetDescription#describedAs(java.lang.String)
+ */
+ public SequencerDetails describedAs( String description ) {
+ configuration().set(DnaLexicon.DESCRIPTION).to(description).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.DnaConfiguration.ConfigurationBuilder#and()
+ */
+ public DnaConfiguration and() {
+ return DnaConfiguration.this;
+ }
+ }
+
+ protected class GraphMimeTypeDetectorDetails implements MimeTypeDetectorDetails {
+ private final Path path;
+
+ protected GraphMimeTypeDetectorDetails( Path path ) {
+ assert path != null;
+ this.path = path;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetName#named(java.lang.String)
+ */
+ public MimeTypeDetectorDetails named( String name ) {
+ configuration().set(DnaLexicon.READABLE_NAME).to(name).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetProperties#with(java.lang.String)
+ */
+ public PropertySetter<MimeTypeDetectorDetails> with( String propertyName )
{
+ return new GraphPropertySetter<MimeTypeDetectorDetails>(path,
propertyName, this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.DnaConfiguration.SetDescription#describedAs(java.lang.String)
+ */
+ public MimeTypeDetectorDetails describedAs( String description ) {
+ configuration().set(DnaLexicon.DESCRIPTION).to(description).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.DnaConfiguration.ConfigurationBuilder#and()
+ */
+ public DnaConfiguration and() {
+ return DnaConfiguration.this;
+ }
+ }
+
/**
* Abstract implementation of {@link ChooseClass} that has a single abstract method
to obtain the interface that should be
* returned when the class name and classpath have been selected.
@@ -743,10 +818,17 @@
* @param <ReturnType> the interface that should be returned when the class
name and classpath have been chosen.
* @author Randall Hauch
*/
- protected abstract class ClassChooser<ComponentClass, ReturnType> implements
ChooseClass<ComponentClass, ReturnType> {
+ protected class ClassChooser<ComponentClass, ReturnType> implements
ChooseClass<ComponentClass, ReturnType> {
+ protected final Path pathOfComponentNode;
+ protected final ReturnType returnObject;
- protected abstract ReturnType getComponentBuilder( String className,
- String... classpath );
+ protected ClassChooser( Path pathOfComponentNode,
+ ReturnType returnObject ) {
+ assert pathOfComponentNode != null;
+ assert returnObject != null;
+ this.pathOfComponentNode = pathOfComponentNode;
+ this.returnObject = returnObject;
+ }
/**
* {@inheritDoc}
@@ -755,13 +837,22 @@
*/
public LoadedFrom<ReturnType> usingClass( final String classname ) {
CheckArg.isNotEmpty(classname, "classname");
+
configuration().set(DnaLexicon.CLASSNAME).to(classname).on(pathOfComponentNode);
return new LoadedFrom<ReturnType>() {
public ReturnType loadedFromClasspath() {
- return getComponentBuilder(classname);
+ return returnObject;
}
public ReturnType loadedFrom( String... classpath ) {
- return getComponentBuilder(classname, classpath);
+ CheckArg.isNotEmpty(classpath, "classpath");
+ if (classpath.length == 1 && classpath[0] != null) {
+
configuration().set(DnaLexicon.CLASSPATH).to(classpath[0]).on(pathOfComponentNode);
+ } else {
+ Object[] remaining = new String[classpath.length - 1];
+ System.arraycopy(classpath, 1, remaining, 0, remaining.length);
+ configuration().set(DnaLexicon.CLASSPATH).to(classpath[0],
remaining).on(pathOfComponentNode);
+ }
+ return returnObject;
}
};
}
@@ -773,34 +864,11 @@
*/
public ReturnType usingClass( Class<? extends ComponentClass> clazz ) {
CheckArg.isNotNull(clazz, "clazz");
- return getComponentBuilder(clazz.getName());
+ return usingClass(clazz.getName()).loadedFromClasspath();
}
}
/**
- * Utility method to instantiate a class.
- *
- * @param <T> the interface or superclass that the instantiated object is to
implement
- * @param interfaceType the interface or superclass type that the instantiated object
is to implement
- * @param className the name of the class
- * @param classloaderNames the names of the class loaders
- * @return the new instance
- */
- @SuppressWarnings( "unchecked" )
- protected <T> T instantiate( Class<T> interfaceType,
- String className,
- String... classloaderNames ) {
- // Load the class and create the instance ...
- try {
- Class<?> clazz =
getExecutionContext().getClassLoader(classloaderNames).loadClass(className);
- return (T)clazz.newInstance();
- } catch (Throwable err) {
- I18n msg = RepositoryI18n.errorCreatingInstanceOfClass;
- throw new DnaConfigurationException(msg.text(className, err.getMessage()),
err);
- }
- }
-
- /**
* Reusable implementation of {@link PropertySetter} that sets the JavaBean-style
property using reflection.
*
* @param <ReturnType>
@@ -864,53 +932,96 @@
}
/**
- * Reusable implementation of {@link PropertySetter} that aggregates the properties
to set to be placed into a map
+ * Reusable implementation of {@link PropertySetter} that sets the property on the
specified node in the configuration graph.
*
* @param <ReturnType>
* @author Randall Hauch
*/
- protected class MappingPropertySetter<ReturnType extends ConfigurationBuilder>
implements PropertySetter<ReturnType> {
+ protected class GraphPropertySetter<ReturnType> implements
PropertySetter<ReturnType> {
+ private final Path path;
private final String beanPropertyName;
private final ReturnType returnObject;
- protected MappingPropertySetter( String beanPropertyName,
- ReturnType returnObject ) {
+ protected GraphPropertySetter( Path path,
+ String beanPropertyName,
+ ReturnType returnObject ) {
+ assert path != null;
assert beanPropertyName != null;
assert returnObject != null;
- this.beanPropertyName = beanPropertyName;
+ this.path = path;
+ this.beanPropertyName =
Inflector.getInstance().lowerCamelCase(beanPropertyName);
this.returnObject = returnObject;
}
public ReturnType setTo( boolean value ) {
- return setTo((Object)value);
+ if (NAMES_TO_MAP.containsKey(beanPropertyName)) {
+
configuration().set(NAMES_TO_MAP.get(beanPropertyName)).to(value).on(path);
+ } else {
+ configuration().set(beanPropertyName).to(value).on(path);
+ }
+ return returnObject;
}
public ReturnType setTo( int value ) {
- return setTo((Object)value);
+ if (NAMES_TO_MAP.containsKey(beanPropertyName)) {
+
configuration().set(NAMES_TO_MAP.get(beanPropertyName)).to(value).on(path);
+ } else {
+ configuration().set(beanPropertyName).to(value).on(path);
+ }
+ return returnObject;
}
public ReturnType setTo( long value ) {
- return setTo((Object)value);
+ if (NAMES_TO_MAP.containsKey(beanPropertyName)) {
+
configuration().set(NAMES_TO_MAP.get(beanPropertyName)).to(value).on(path);
+ } else {
+ configuration().set(beanPropertyName).to(value).on(path);
+ }
+ return returnObject;
}
public ReturnType setTo( short value ) {
- return setTo((Object)value);
+ if (NAMES_TO_MAP.containsKey(beanPropertyName)) {
+
configuration().set(NAMES_TO_MAP.get(beanPropertyName)).to(value).on(path);
+ } else {
+ configuration().set(beanPropertyName).to(value).on(path);
+ }
+ return returnObject;
}
public ReturnType setTo( float value ) {
- return setTo((Object)value);
+ if (NAMES_TO_MAP.containsKey(beanPropertyName)) {
+
configuration().set(NAMES_TO_MAP.get(beanPropertyName)).to(value).on(path);
+ } else {
+ configuration().set(beanPropertyName).to(value).on(path);
+ }
+ return returnObject;
}
public ReturnType setTo( double value ) {
- return setTo((Object)value);
+ if (NAMES_TO_MAP.containsKey(beanPropertyName)) {
+
configuration().set(NAMES_TO_MAP.get(beanPropertyName)).to(value).on(path);
+ } else {
+ configuration().set(beanPropertyName).to(value).on(path);
+ }
+ return returnObject;
}
public ReturnType setTo( String value ) {
- return setTo((Object)value);
+ if (NAMES_TO_MAP.containsKey(beanPropertyName)) {
+
configuration().set(NAMES_TO_MAP.get(beanPropertyName)).to(value).on(path);
+ } else {
+ configuration().set(beanPropertyName).to(value).on(path);
+ }
+ return returnObject;
}
public ReturnType setTo( Object value ) {
- returnObject.getProperties().put(beanPropertyName, value);
+ if (NAMES_TO_MAP.containsKey(beanPropertyName)) {
+
configuration().set(NAMES_TO_MAP.get(beanPropertyName)).to(value).on(path);
+ } else {
+ configuration().set(beanPropertyName).to(value).on(path);
+ }
return returnObject;
}
}
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.java 2009-04-23
16:29:28 UTC (rev 848)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.java 2009-04-23
16:43:27 UTC (rev 849)
@@ -21,23 +21,44 @@
*/
package org.jboss.dna.repository;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.collection.Problems;
+import org.jboss.dna.common.collection.SimpleProblems;
import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.JcrLexicon;
+import org.jboss.dna.graph.JcrMixLexicon;
+import org.jboss.dna.graph.JcrNtLexicon;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.Node;
+import org.jboss.dna.graph.Subgraph;
import org.jboss.dna.graph.connector.RepositoryConnection;
import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.RepositorySourceException;
-import org.jboss.dna.repository.DnaConfiguration.DnaMimeTypeDetectorDetails;
-import org.jboss.dna.repository.DnaConfiguration.DnaRepositoryDetails;
-import org.jboss.dna.repository.DnaConfiguration.DnaSequencerDetails;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.graph.property.PathExpression;
+import org.jboss.dna.graph.property.PathNotFoundException;
+import org.jboss.dna.graph.property.Property;
+import org.jboss.dna.repository.mimetype.MimeTypeDetectorConfig;
import org.jboss.dna.repository.observation.ObservationService;
+import org.jboss.dna.repository.sequencer.SequencerConfig;
import org.jboss.dna.repository.sequencer.SequencingService;
import org.jboss.dna.repository.service.AdministeredService;
+import org.jboss.dna.repository.util.JcrExecutionContext;
+import org.jboss.dna.repository.util.SessionFactory;
+import org.jboss.dna.repository.util.SimpleSessionFactory;
/**
* @author Randall Hauch
@@ -47,6 +68,7 @@
public static final String CONFIGURATION_REPOSITORY_NAME =
"dna:configuration";
+ private final Problems problems;
private final ExecutionContext context;
private final List<AdministeredService> services;
@@ -58,33 +80,39 @@
private final RepositoryConnectionFactory connectionFactory;
DnaEngine( DnaConfiguration configuration ) {
- this.context = new ExecutionContext();
+ this.problems = new SimpleProblems();
- DnaRepositoryDetails configSource =
configuration.repositories.get(CONFIGURATION_REPOSITORY_NAME);
- assert configSource != null : "Must specify a repository source named "
+ CONFIGURATION_REPOSITORY_NAME;
+ // Use the configuration's context ...
+ this.context = configuration.context();
- // Use a magic number for now
- executorService = new ScheduledThreadPoolExecutor(10);
+ // Add the configuration source to the repository library ...
+ final DnaConfiguration.Source configSourceInfo =
configuration.configurationSource;
+ final RepositorySource configSource = configSourceInfo.source;
+ RepositoryLibrary library = new RepositoryLibrary();
+ library.addSource(configSource);
- observationService = null; // new ObservationService(null);
+ // Create the RepositoryService, pointing it to the configuration repository ...
+ Path pathToConfigurationRoot = configSourceInfo.path;
+ repositoryService = new RepositoryService(library, configSource.getName(),
"", pathToConfigurationRoot, context);
- RepositoryLibrary library = new RepositoryLibrary();
- for (DnaRepositoryDetails details : configuration.repositories.values()) {
- // Adding configuration source to the library until proven wrong!
- library.addSource(details.getRepositorySource());
+ for (MimeTypeDetectorConfig config : loadMimeTypeDetectors(problems, context,
configSourceInfo)) {
+ library.getMimeTypeDetectors().addDetector(config);
}
- for (DnaMimeTypeDetectorDetails details :
configuration.mimeTypeDetectors.values()) {
-
library.getMimeTypeDetectors().addDetector(details.getMimeTypeDetectorConfig());
- }
- repositoryService = new RepositoryService(library,
configSource.getRepositorySource().getName(), "", context);
-
+ // Create the sequencing service ...
+ executorService = new ScheduledThreadPoolExecutor(10); // Use a magic number for
now
sequencingService = new SequencingService();
+ SessionFactory sessionFactory = new SimpleSessionFactory();
+ JcrExecutionContext jcrContext = new JcrExecutionContext(context, sessionFactory,
"");
+ sequencingService.setExecutionContext(jcrContext);
sequencingService.setExecutorService(executorService);
- for (DnaSequencerDetails details : configuration.sequencers.values()) {
- sequencingService.addSequencer(details.getSequencerConfig());
+ for (SequencerConfig sequencerConfig : loadSequencingConfigurations(problems,
context, configSourceInfo)) {
+ sequencingService.addSequencer(sequencerConfig);
}
+ // Create the observation service ...
+ observationService = null; // new ObservationService(null);
+
this.services = Arrays.asList(new AdministeredService[] { /* observationService,
*/repositoryService, sequencingService,});
connectionFactory = new RepositoryConnectionFactory() {
@@ -99,6 +127,145 @@
};
}
+ protected static List<MimeTypeDetectorConfig> loadMimeTypeDetectors( Problems
problems,
+ ExecutionContext
context,
+
DnaConfiguration.Source source ) {
+ List<MimeTypeDetectorConfig> detectors = new
ArrayList<MimeTypeDetectorConfig>();
+ Graph graph = Graph.create(source.source, context);
+ Path pathToSequencersNode =
context.getValueFactories().getPathFactory().create(source.path,
+
DnaLexicon.MIME_TYPE_DETECTORS);
+ try {
+ Subgraph subgraph = graph.getSubgraphOfDepth(2).at(pathToSequencersNode);
+
+ Set<Name> skipProperties = new HashSet<Name>();
+ skipProperties.add(DnaLexicon.READABLE_NAME);
+ skipProperties.add(DnaLexicon.DESCRIPTION);
+ skipProperties.add(DnaLexicon.CLASSNAME);
+ skipProperties.add(DnaLexicon.CLASSPATH);
+ skipProperties.add(DnaLexicon.PATH_EXPRESSIONS);
+ Set<String> skipNamespaces = new HashSet<String>();
+ skipNamespaces.add(JcrLexicon.Namespace.URI);
+ skipNamespaces.add(JcrNtLexicon.Namespace.URI);
+ skipNamespaces.add(JcrMixLexicon.Namespace.URI);
+
+ for (Location sequencerLocation : subgraph.getRoot().getChildren()) {
+ Node sequencerNode = subgraph.getNode(sequencerLocation);
+ String name = stringValueOf(context, sequencerNode,
DnaLexicon.READABLE_NAME);
+ String desc = stringValueOf(context, sequencerNode,
DnaLexicon.DESCRIPTION);
+ String classname = stringValueOf(context, sequencerNode,
DnaLexicon.CLASSNAME);
+ String[] classpath = stringValuesOf(context, sequencerNode,
DnaLexicon.CLASSPATH);
+ Map<String, Object> properties = new HashMap<String,
Object>();
+ for (Property property : sequencerNode.getProperties()) {
+ Name propertyName = property.getName();
+ if (skipNamespaces.contains(propertyName.getNamespaceUri()))
continue;
+ if (skipProperties.contains(propertyName)) continue;
+ if (property.isSingle()) {
+ properties.put(propertyName.getLocalName(),
property.getFirstValue());
+ } else {
+ properties.put(propertyName.getLocalName(),
property.getValuesAsArray());
+ }
+ }
+ MimeTypeDetectorConfig config = new MimeTypeDetectorConfig(name, desc,
properties, classname, classpath);
+ detectors.add(config);
+ }
+ } catch (PathNotFoundException e) {
+ // no detectors registered ...
+ }
+ return detectors;
+ }
+
+ protected static List<SequencerConfig> loadSequencingConfigurations( Problems
problems,
+ ExecutionContext
context,
+
DnaConfiguration.Source source ) {
+ List<SequencerConfig> configs = new ArrayList<SequencerConfig>();
+ Graph graph = Graph.create(source.source, context);
+ Path pathToSequencersNode =
context.getValueFactories().getPathFactory().create(source.path, DnaLexicon.SEQUENCERS);
+ try {
+ Subgraph subgraph = graph.getSubgraphOfDepth(2).at(pathToSequencersNode);
+
+ Set<Name> skipProperties = new HashSet<Name>();
+ skipProperties.add(DnaLexicon.READABLE_NAME);
+ skipProperties.add(DnaLexicon.DESCRIPTION);
+ skipProperties.add(DnaLexicon.CLASSNAME);
+ skipProperties.add(DnaLexicon.CLASSPATH);
+ skipProperties.add(DnaLexicon.PATH_EXPRESSIONS);
+ Set<String> skipNamespaces = new HashSet<String>();
+ skipNamespaces.add(JcrLexicon.Namespace.URI);
+ skipNamespaces.add(JcrNtLexicon.Namespace.URI);
+ skipNamespaces.add(JcrMixLexicon.Namespace.URI);
+
+ for (Location sequencerLocation : subgraph.getRoot().getChildren()) {
+ Node sequencerNode = subgraph.getNode(sequencerLocation);
+ String name = stringValueOf(context, sequencerNode,
DnaLexicon.READABLE_NAME);
+ String desc = stringValueOf(context, sequencerNode,
DnaLexicon.DESCRIPTION);
+ String classname = stringValueOf(context, sequencerNode,
DnaLexicon.CLASSNAME);
+ String[] classpath = stringValuesOf(context, sequencerNode,
DnaLexicon.CLASSPATH);
+ String[] expressionStrings = stringValuesOf(context, sequencerNode,
DnaLexicon.PATH_EXPRESSIONS);
+ List<PathExpression> pathExpressions = new
ArrayList<PathExpression>();
+ if (expressionStrings != null) {
+ for (String expressionString : expressionStrings) {
+ try {
+
pathExpressions.add(PathExpression.compile(expressionString));
+ } catch (Throwable t) {
+ problems.addError(t,
+
RepositoryI18n.pathExpressionIsInvalidOnSequencer,
+ expressionString,
+ name,
+ t.getLocalizedMessage());
+ }
+ }
+ }
+ String[] goodExpressionStrings = new String[pathExpressions.size()];
+ for (int i = 0; i != pathExpressions.size(); ++i) {
+ PathExpression expression = pathExpressions.get(i);
+ goodExpressionStrings[i] = expression.getExpression();
+ }
+ Map<String, Object> properties = new HashMap<String,
Object>();
+ for (Property property : sequencerNode.getProperties()) {
+ Name propertyName = property.getName();
+ if (skipNamespaces.contains(propertyName.getNamespaceUri()))
continue;
+ if (skipProperties.contains(propertyName)) continue;
+ if (property.isSingle()) {
+ properties.put(propertyName.getLocalName(),
property.getFirstValue());
+ } else {
+ properties.put(propertyName.getLocalName(),
property.getValuesAsArray());
+ }
+ }
+ SequencerConfig config = new SequencerConfig(name, desc, properties,
classname, classpath, goodExpressionStrings);
+ configs.add(config);
+ }
+ } catch (PathNotFoundException e) {
+ // no detectors registered ...
+ }
+ return configs;
+ }
+
+ private static String stringValueOf( ExecutionContext context,
+ Node node,
+ Name propertyName ) {
+ Property property = node.getProperty(propertyName);
+ if (property == null) return null;
+ if (property.isEmpty()) return null;
+ return
context.getValueFactories().getStringFactory().create(property.getFirstValue());
+ }
+
+ private static String[] stringValuesOf( ExecutionContext context,
+ Node node,
+ Name propertyName ) {
+ Property property = node.getProperty(propertyName);
+ if (property == null) return null;
+ return
context.getValueFactories().getStringFactory().create(property.getValuesAsArray());
+ }
+
+ /**
+ * Get the problems that were encountered when setting up this engine from the
configuration.
+ *
+ * @return the problems, which may be empty but will never be null
+ */
+ public Problems getProblems() {
+ return problems;
+ }
+
/*
* Lookup methods
*/
Added: trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaLexicon.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaLexicon.java
(rev 0)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaLexicon.java 2009-04-23
16:43:27 UTC (rev 849)
@@ -0,0 +1,45 @@
+/*
+ * JBoss DNA (
http://www.jboss.org/dna)
+ * 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.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * 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.
+ *
+ * JBoss DNA 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 software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.dna.repository;
+
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.basic.BasicName;
+
+/**
+ * @author Randall Hauch
+ */
+public class DnaLexicon extends org.jboss.dna.graph.DnaLexicon {
+
+ public static final Name SOURCES = new BasicName(Namespace.URI,
"sources");
+ public static final Name SOURCE = new BasicName(Namespace.URI, "source");
+ public static final Name READABLE_NAME = new BasicName(Namespace.URI,
"readableName");
+ public static final Name DESCRIPTION = new BasicName(Namespace.URI,
"description");
+ public static final Name SEQUENCERS = new BasicName(Namespace.URI,
"sequencers");
+ public static final Name SEQUENCER = new BasicName(Namespace.URI,
"sequencer");
+ public static final Name PATH_EXPRESSIONS = new BasicName(Namespace.URI,
"pathExpressions");
+ public static final Name MIME_TYPE_DETECTORS = new BasicName(Namespace.URI,
"mimeTypeDetectors");
+ public static final Name MIME_TYPE_DETECTOR = new BasicName(Namespace.URI,
"mimeTypeDetector");
+ public static final Name RETRY_LIMIT = new BasicName(Namespace.URI,
"retryLimit");
+ public static final Name DEFAULT_CACHE_POLICY = new BasicName(Namespace.URI,
"defaultCachePolicy");
+}
Property changes on:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaLexicon.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryI18n.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryI18n.java 2009-04-23
16:29:28 UTC (rev 848)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryI18n.java 2009-04-23
16:43:27 UTC (rev 849)
@@ -37,6 +37,7 @@
public static I18n errorCreatingInstanceOfClass;
public static I18n errorCreatingInstanceOfClassUsingClassLoaders;
public static I18n errorSettingJavaBeanPropertyOnInstanceOfClass;
+ public static I18n pathExpressionIsInvalidOnSequencer;
// Services and Repository
public static I18n invalidStateString;
@@ -113,6 +114,7 @@
// General
public static I18n invalidRepositoryNodePath;
+ public static I18n unableToLoadClass;
public static I18n unableToLoadClassUsingClasspath;
public static I18n unableToInstantiateClassUsingClasspath;
public static I18n unableToAccessClassUsingClasspath;
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java 2009-04-23
16:29:28 UTC (rev 848)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java 2009-04-23
16:43:27 UTC (rev 849)
@@ -35,9 +35,9 @@
import org.jboss.dna.common.util.Logger;
import org.jboss.dna.common.util.Reflection;
import org.jboss.dna.connector.federation.FederationException;
-import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.JcrLexicon;
import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.Node;
import org.jboss.dna.graph.Subgraph;
@@ -205,7 +205,8 @@
// Read the configuration and repository source nodes (children under
"/dna:sources") ...
Graph graph = Graph.create(getConfigurationSourceName(), sources, context);
- Path pathToSourcesNode =
context.getValueFactories().getPathFactory().create(pathToConfigurationRoot,
"dna:sources");
+ Path pathToSourcesNode =
context.getValueFactories().getPathFactory().create(pathToConfigurationRoot,
+
DnaLexicon.SOURCES);
try {
String workspaceName = getConfigurationWorkspaceName();
if (workspaceName != null) graph.useWorkspace(workspaceName);
@@ -266,14 +267,10 @@
problems.addError(err, RepositoryI18n.unableToInstantiateClassUsingClasspath,
classname, classpath);
}
- // We need to set the name using the local name of the node, so hack this by
putting another name property
- // into the map of properties. Since only the local name is used, we don't
care what the namespace of the
- // fake property name is, so create something bogus. However, it really won't
hurt if this happens to override an existing
- // property.
- String fakeUri = DnaLexicon.Namespace.URI + "/300939b9dg93kd9gb";
- Name nameName = context.getValueFactories().getNameFactory().create(fakeUri,
"name");
- Property nameProperty = context.getPropertyFactory().create(nameName,
path.getLastSegment().getName().getLocalName());
- properties.put(nameName, nameProperty);
+ // We need to set the name using the local name of the node...
+ Property nameProperty = context.getPropertyFactory().create(JcrLexicon.NAME,
+
path.getLastSegment().getName().getLocalName());
+ properties.put(JcrLexicon.NAME, nameProperty);
// Now set all the properties that we can, ignoring any property that doesn't
fit the pattern ...
Reflection reflection = new Reflection(source.getClass());
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleSessionFactory.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleSessionFactory.java 2009-04-23
16:29:28 UTC (rev 848)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleSessionFactory.java 2009-04-23
16:43:27 UTC (rev 849)
@@ -34,21 +34,9 @@
import org.jboss.dna.repository.RepositoryI18n;
/**
- * A SessionFactory implementation that creates {@link Session} instances using {@link
Repository} instances registered in JNDI.
+ * A SessionFactory implementation that creates {@link Session} instances from a map of
named {@link Repository} references
+ * managed by this factory.
* <p>
- * This factory using a naming convention where the name supplied to the {@link
#createSession(String)} contains both the name of
- * the repository and the name of the workspace. Typically, this is
<i><code>repositoryName/workspaceName</code></i>, where
- * <code>repositoryName</code> is the JNDI name under which the Repository
instance was bound, and <code>workspaceName</code>
- * is the name of the workspace. Note that this method looks for the last delimiter in
the whole name to distinguish between the
- * repository and workspace names.
- * </p>
- * <p>
- * For example, if
"<code>java:comp/env/repository/dataRepository/myWorkspace</code>"
is passed to the
- * {@link #createSession(String)} method, this factory will look for a {@link Repository}
instance registered in JDNI with the
- * name "<code>java:comp/env/repository/dataRepository</code>" and
use it to {@link Repository#login(String) create a session}
- * to the workspace named "<code>myWorkspace</code>".
- * </p>
- * <p>
* By default, this factory creates an anonymous JCR session. To use sessions with
specific {@link Credentials}, simply
* {@link #registerCredentials(String, Credentials) register} credentials for the
appropriate repository/workspace name. For
* security reasons, it is not possible to retrieve the Credentials once registered with
this factory.
Modified:
trunk/dna-repository/src/main/resources/org/jboss/dna/repository/RepositoryI18n.properties
===================================================================
---
trunk/dna-repository/src/main/resources/org/jboss/dna/repository/RepositoryI18n.properties 2009-04-23
16:29:28 UTC (rev 848)
+++
trunk/dna-repository/src/main/resources/org/jboss/dna/repository/RepositoryI18n.properties 2009-04-23
16:43:27 UTC (rev 849)
@@ -24,6 +24,7 @@
errorCreatingInstanceOfClass = Attempt to create instance of {0} resulted in error: {1}
errorCreatingInstanceOfClassUsingClassLoaders = Attempt to create instance of {0} using
classloader path {1} resulted in error: {2}
errorSettingJavaBeanPropertyOnInstanceOfClass = Attempt to set {0} property on {1}
instance resulted in error: {2}
+pathExpressionIsInvalidOnSequencer = The path expression "{0}" is invalid on
the "{1}" sequencer: {2}
invalidStateString = Invalid state parameter "{0}"
serviceShutdowAndMayNotBeStarted = The {0} has been shutdown and may not be (re)started
@@ -93,6 +94,7 @@
errorUnregisteringWorkspaceListenerWhileShuttingDownObservationService = Error
unregistering workspace listener while shutting down observation service
invalidRepositoryNodePath = The repository node path "{0}" is not valid: {1}
+unableToLoadClass = Unable to load class "{0}"
unableToLoadClassUsingClasspath = Unable to load class "{0}" using classpath
"{1}"
unableToInstantiateClassUsingClasspath = Unable to instantiate class "{0}"
using classpath "{1}"
unableToAccessClassUsingClasspath = Unable to access class "{0}" using
classpath "{1}"
Modified:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaConfigurationTest.java
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaConfigurationTest.java 2009-04-23
16:29:28 UTC (rev 848)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaConfigurationTest.java 2009-04-23
16:43:27 UTC (rev 849)
@@ -24,16 +24,18 @@
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsInstanceOf.instanceOf;
import static org.hamcrest.core.IsNull.notNullValue;
-import static org.hamcrest.core.IsNull.nullValue;
+import static org.jboss.dna.graph.IsNodeWithChildren.hasChild;
+import static org.jboss.dna.graph.IsNodeWithProperty.hasProperty;
import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.mock;
+import java.util.UUID;
import org.jboss.dna.graph.ExecutionContext;
-import org.jboss.dna.graph.connector.RepositorySource;
+import org.jboss.dna.graph.Subgraph;
+import org.jboss.dna.graph.cache.CachePolicy;
+import org.jboss.dna.graph.cache.ImmutableCachePolicy;
import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
-import org.jboss.dna.graph.mimetype.MimeTypeDetector;
-import org.jboss.dna.repository.DnaConfiguration.DnaSequencerDetails;
+import org.jboss.dna.graph.mimetype.ExtensionBasedMimeTypeDetector;
+import org.jboss.dna.graph.property.Path;
import org.jboss.dna.repository.sequencer.MockSequencerA;
-import org.jboss.dna.repository.sequencer.MockSequencerB;
import org.junit.Before;
import org.junit.Test;
@@ -51,6 +53,10 @@
configuration = new DnaConfiguration();
}
+ protected Path.Segment segment( String segment ) {
+ return context.getValueFactories().getPathFactory().createSegment(segment);
+ }
+
@Test
public void shouldAllowCreatingWithNoArguments() {
configuration = new DnaConfiguration();
@@ -62,6 +68,11 @@
}
@Test
+ public void shouldHaveDefaultConfigurationSourceIfNotSpecified() {
+ assertThat(configuration.graph(), is(notNullValue()));
+ }
+
+ @Test
public void shouldAllowSpecifyingConfigurationRepository() {
DnaConfiguration config = configuration.withConfigurationRepository()
.usingClass("org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource")
@@ -71,145 +82,225 @@
.setTo(5)
.with("name")
.setTo("repository name")
- .and();
+ .and()
+ .save();
assertThat(config, is(notNullValue()));
- assertThat(config.repositories.get(null), is(nullValue()));
+ assertThat(config.configurationSource.source,
is(instanceOf(InMemoryRepositorySource.class)));
+ InMemoryRepositorySource source =
(InMemoryRepositorySource)config.configurationSource.source;
+ assertThat(source.getName(), is("repository name"));
+ assertThat(source.getRetryLimit(), is(5));
}
@Test
public void shouldAllowAddingRepositorySourceInstance() {
- RepositorySource newSource = mock(RepositorySource.class);
- configuration.addRepository(newSource);
+ UUID rootUuid = UUID.randomUUID();
+ CachePolicy cachePolicy = new ImmutableCachePolicy(100);
+ InMemoryRepositorySource newSource = new InMemoryRepositorySource();
+ newSource.setName("name");
+ newSource.setDefaultCachePolicy(cachePolicy);
+ newSource.setDefaultWorkspaceName("default workspace name");
+ newSource.setRetryLimit(100);
+ newSource.setRootNodeUuid(rootUuid);
+
+ // Update the configuration and save it ...
+ configuration.addRepository(newSource).save();
+
+ // Verify that the graph has been updated correctly ...
+ Subgraph subgraph =
configuration.graph().getSubgraphOfDepth(3).at("/");
+ assertThat(subgraph.getNode("/dna:sources"), is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/name"), is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/name"),
hasProperty(DnaLexicon.READABLE_NAME, "name"));
+ assertThat(subgraph.getNode("/dna:sources/name"),
hasProperty(DnaLexicon.RETRY_LIMIT, 100));
+ assertThat(subgraph.getNode("/dna:sources/name"),
hasProperty(DnaLexicon.DEFAULT_CACHE_POLICY, cachePolicy));
+ assertThat(subgraph.getNode("/dna:sources/name"),
hasProperty("defaultWorkspaceName", "default workspace name"));
+ assertThat(subgraph.getNode("/dna:sources/name"),
hasProperty("rootNodeUuid", rootUuid));
}
@Test
public void shouldAllowAddingRepositorySourceByClassNameAndSettingProperties() {
- DnaConfiguration config =
configuration.addRepository(DnaEngine.CONFIGURATION_REPOSITORY_NAME)
-
.usingClass("org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource")
- .loadedFromClasspath()
- .describedAs("description")
- .with("retryLimit")
- .setTo(5)
- .with("name")
- .setTo("repository name")
- .and();
- assertThat(config, is(notNullValue()));
+ // Update the configuration and save it ...
+ configuration.addRepository("Source1")
+ .usingClass(InMemoryRepositorySource.class.getName())
+ .loadedFromClasspath()
+ .describedAs("description")
+ .with("retryLimit")
+ .setTo(5)
+ .and()
+ .save();
- RepositorySource source =
config.repositories.get(DnaEngine.CONFIGURATION_REPOSITORY_NAME).getRepositorySource();
- assertThat(source, is(notNullValue()));
- assertThat(source, is(instanceOf(InMemoryRepositorySource.class)));
+ // Verify that the graph has been updated correctly ...
+ Subgraph subgraph =
configuration.graph().getSubgraphOfDepth(3).at("/");
+ assertThat(subgraph.getNode("/dna:sources"), is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.READABLE_NAME, "Source1"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.RETRY_LIMIT, 5));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.CLASSNAME,
+
InMemoryRepositorySource.class.getName()));
+ }
- InMemoryRepositorySource isource = (InMemoryRepositorySource)source;
- assertThat(isource.getRetryLimit(), is(5));
- assertThat(isource.getName(), is("repository name"));
+ @Test
+ public void
shouldAllowAddingRepositorySourceByClassNameAndClasspathAndSettingProperties() {
+ // Update the configuration and save it ...
+ configuration.addRepository("Source1")
+ .usingClass(InMemoryRepositorySource.class.getName())
+ .loadedFrom("cp1", "cp2")
+ .describedAs("description")
+ .with("retryLimit")
+ .setTo(5)
+ .and()
+ .save();
+
+ // Verify that the graph has been updated correctly ...
+ Subgraph subgraph =
configuration.graph().getSubgraphOfDepth(3).at("/");
+ assertThat(subgraph.getNode("/dna:sources"), is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.READABLE_NAME, "Source1"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.RETRY_LIMIT, 5));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.CLASSNAME,
+
InMemoryRepositorySource.class.getName()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.CLASSPATH, "cp1", "cp2"));
}
@Test
public void shouldAllowAddingRepositorySourceByClassReferenceAndSettingProperties()
{
- DnaConfiguration config =
configuration.addRepository(DnaEngine.CONFIGURATION_REPOSITORY_NAME)
-
.usingClass(InMemoryRepositorySource.class)
- .describedAs("description")
- .with("retryLimit")
- .setTo(5)
- .with("name")
- .setTo("repository name")
- .and();
+ // Update the configuration and save it ...
+ configuration.addRepository("Source1")
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("description")
+ .with("retryLimit")
+ .setTo(5)
+ .and()
+ .save();
- assertThat(config, is(notNullValue()));
- assertThat(config.repositories.get(null), is(nullValue()));
-
- RepositorySource source =
config.repositories.get(DnaEngine.CONFIGURATION_REPOSITORY_NAME).getRepositorySource();
- assertThat(source, is(notNullValue()));
- assertThat(source, is(instanceOf(InMemoryRepositorySource.class)));
-
- InMemoryRepositorySource isource = (InMemoryRepositorySource)source;
- assertThat(isource.getRetryLimit(), is(5));
- assertThat(isource.getName(), is("repository name"));
+ // Verify that the graph has been updated correctly ...
+ Subgraph subgraph =
configuration.graph().getSubgraphOfDepth(3).at("/");
+ assertThat(subgraph.getNode("/dna:sources"), is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.READABLE_NAME, "Source1"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.RETRY_LIMIT, 5));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.DESCRIPTION, "description"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.CLASSNAME,
+
InMemoryRepositorySource.class.getName()));
}
@Test
public void shouldAllowOverwritingRepositorySourceByRepositoryName() {
- DnaConfiguration config =
configuration.addRepository(DnaEngine.CONFIGURATION_REPOSITORY_NAME)
-
.usingClass(InMemoryRepositorySource.class)
- .describedAs("description")
- .with("retryLimit")
- .setTo(3)
- .and()
-
.addRepository(DnaEngine.CONFIGURATION_REPOSITORY_NAME)
-
.usingClass(InMemoryRepositorySource.class)
- .describedAs("description")
- .with("name")
- .setTo("repository name")
- .and();
+ // Update the configuration and save it ...
+ configuration.addRepository("Source1")
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("description")
+ .with("retryLimit")
+ .setTo(3)
+ .and()
+ .addRepository("Source1")
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("new description")
+ .with("retryLimit")
+ .setTo(6)
+ .and()
+ .save();
- assertThat(config, is(notNullValue()));
- assertThat(config.repositories.get(null), is(nullValue()));
-
- RepositorySource source =
config.repositories.get(DnaEngine.CONFIGURATION_REPOSITORY_NAME).getRepositorySource();
- assertThat(source, is(notNullValue()));
- assertThat(source, is(instanceOf(InMemoryRepositorySource.class)));
-
- InMemoryRepositorySource isource = (InMemoryRepositorySource)source;
- // This relies on the default retry limit for an InMemoryRepositorySource being
0
- // If the original source was not overwritten, this would be 3
- assertThat(isource.getRetryLimit(), is(0));
- assertThat(isource.getName(), is("repository name"));
+ // Verify that the graph has been updated correctly ...
+ Subgraph subgraph =
configuration.graph().getSubgraphOfDepth(3).at("/");
+ assertThat(subgraph.getNode("/dna:sources"), is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources").getChildren(),
hasChild(segment("Source1")));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.READABLE_NAME, "Source1"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.RETRY_LIMIT, 6));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.DESCRIPTION, "new description"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.CLASSNAME,
+
InMemoryRepositorySource.class.getName()));
}
@Test
public void shouldAllowAddingMimeTypeDetector() {
- RepositorySource newSource = mock(RepositorySource.class);
- MimeTypeDetector newDetector = mock(MimeTypeDetector.class);
- DnaConfiguration config = configuration.addRepository(newSource)
- .addMimeTypeDetector("default")
- .usingClass(newDetector.getClass())
- .describedAs("default mime type
detector")
- .and();
+ // Update the configuration and save it ...
+ configuration.addRepository("Source1")
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("description")
+ .and()
+ .addMimeTypeDetector("detector")
+ .usingClass(ExtensionBasedMimeTypeDetector.class)
+ .describedAs("default detector")
+ .and()
+ .save();
- assertThat(config, is(notNullValue()));
-
assertThat(config.mimeTypeDetectors.get("default").getMimeTypeDetector(),
instanceOf(MimeTypeDetector.class));
- assertThat(config.mimeTypeDetectors.get("invalid name"),
is(nullValue()));
- assertThat(config.mimeTypeDetectors.get("default").getDescription(),
is("default mime type detector"));
+ // Verify that the graph has been updated correctly ...
+ Subgraph subgraph =
configuration.graph().getSubgraphOfDepth(3).at("/");
+ assertThat(subgraph.getNode("/dna:sources").getChildren(),
hasChild(segment("Source1")));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.READABLE_NAME, "Source1"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.DESCRIPTION, "description"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.CLASSNAME,
+
InMemoryRepositorySource.class.getName()));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors").getChildren(),
hasChild(segment("detector")));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors/detector"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors/detector"),
hasProperty(DnaLexicon.READABLE_NAME, "detector"));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors/detector"),
hasProperty(DnaLexicon.DESCRIPTION, "default detector"));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors/detector"),
+ hasProperty(DnaLexicon.CLASSNAME,
ExtensionBasedMimeTypeDetector.class.getName()));
}
@Test
public void shouldAllowAddingSequencer() {
- RepositorySource newSource = mock(RepositorySource.class);
+ // Update the configuration and save it ...
+ configuration.addRepository("Source1")
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("description")
+ .named("A Source")
+ .and()
+ .addSequencer("sequencerA")
+ .usingClass(MockSequencerA.class)
+ .named("The (Main) Sequencer")
+ .describedAs("Mock Sequencer A")
+ // .sequencingFrom("/foo/source")
+ // .andOutputtingTo("/foo/target")
+ .sequencingFrom("/bar/source")
+ .andOutputtingTo("/bar/target")
+ .and()
+ .save();
- DnaConfiguration config = configuration.addRepository(newSource)
- .addSequencer("sequencerA")
- .usingClass(MockSequencerA.class)
- .describedAs("Mock Sequencer
A")
- .sequencingFrom("/foo/source")
- .andOutputtingTo("/foo/target")
- .sequencingFrom("/bar/source")
- .andOutputtingTo("/bar/target")
- .and()
- .addSequencer("sequencerB")
- .usingClass(MockSequencerB.class)
- .sequencingFrom("/baz/source")
- .andOutputtingTo("/baz/target")
- .describedAs("Mock Sequencer
B")
- .and();
+ // Verify that the graph has been updated correctly ...
+ Subgraph subgraph =
configuration.graph().getSubgraphOfDepth(3).at("/");
+ assertThat(subgraph.getNode("/dna:sources").getChildren(),
hasChild(segment("Source1")));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.READABLE_NAME, "A Source"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.DESCRIPTION, "description"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.CLASSNAME,
+
InMemoryRepositorySource.class.getName()));
+ assertThat(subgraph.getNode("/dna:sequencers").getChildren(),
hasChild(segment("sequencerA")));
+ assertThat(subgraph.getNode("/dna:sequencers/sequencerA"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sequencers/sequencerA"),
hasProperty(DnaLexicon.READABLE_NAME, "The (Main) Sequencer"));
+ assertThat(subgraph.getNode("/dna:sequencers/sequencerA"),
hasProperty(DnaLexicon.DESCRIPTION, "Mock Sequencer A"));
+ assertThat(subgraph.getNode("/dna:sequencers/sequencerA"),
hasProperty(DnaLexicon.CLASSNAME,
+
MockSequencerA.class.getName()));
+
System.out.println(subgraph.getNode("/dna:sequencers/sequencerA").getProperty(DnaLexicon.PATH_EXPRESSIONS));
+ assertThat(subgraph.getNode("/dna:sequencers/sequencerA"),
hasProperty(DnaLexicon.PATH_EXPRESSIONS,
+ // "/foo/source => /foo/target",
+
"/bar/source => /bar/target"));
+ }
- assertThat(config, is(notNullValue()));
- assertThat(config.sequencers.get("default"), is(nullValue()));
- assertThat(config.sequencers.get("sequencerA").getSequencer(),
instanceOf(MockSequencerA.class));
- assertThat(config.sequencers.get("sequencerB").getSequencer(),
instanceOf(MockSequencerB.class));
+ @Test
+ public void shouldAllowConfigurationInMultipleSteps() {
+
configuration.addRepository("Source1").usingClass(InMemoryRepositorySource.class).describedAs("description");
+ configuration.addMimeTypeDetector("detector")
+ .usingClass(ExtensionBasedMimeTypeDetector.class)
+ .describedAs("default detector");
+ configuration.save();
- DnaSequencerDetails detailsA = config.sequencers.get("sequencerA");
- assertThat(detailsA.getDescription(), is("Mock Sequencer A"));
- assertThat(detailsA.sourcePathExpressions.size(), is(2));
- assertThat(detailsA.sourcePathExpressions.get(0).toString(),
is("/foo/source"));
- assertThat(detailsA.targetPathExpressions.get(0).toString(),
is("/foo/target"));
- assertThat(detailsA.sourcePathExpressions.get(1).toString(),
is("/bar/source"));
- assertThat(detailsA.targetPathExpressions.get(1).toString(),
is("/bar/target"));
-
- DnaSequencerDetails detailsB = config.sequencers.get("sequencerB");
- assertThat(detailsB.getDescription(), is("Mock Sequencer B"));
- assertThat(detailsB.sourcePathExpressions.size(), is(1));
- assertThat(detailsB.sourcePathExpressions.get(0).toString(),
is("/baz/source"));
- assertThat(detailsB.targetPathExpressions.get(0).toString(),
is("/baz/target"));
+ // Verify that the graph has been updated correctly ...
+ Subgraph subgraph =
configuration.graph().getSubgraphOfDepth(3).at("/");
+ assertThat(subgraph.getNode("/dna:sources").getChildren(),
hasChild(segment("Source1")));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.READABLE_NAME, "Source1"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.DESCRIPTION, "description"));
+ assertThat(subgraph.getNode("/dna:sources/Source1"),
hasProperty(DnaLexicon.CLASSNAME,
+
InMemoryRepositorySource.class.getName()));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors").getChildren(),
hasChild(segment("detector")));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors/detector"),
is(notNullValue()));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors/detector"),
hasProperty(DnaLexicon.READABLE_NAME, "detector"));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors/detector"),
hasProperty(DnaLexicon.DESCRIPTION, "default detector"));
+ assertThat(subgraph.getNode("/dna:mimeTypeDetectors/detector"),
+ hasProperty(DnaLexicon.CLASSNAME,
ExtensionBasedMimeTypeDetector.class.getName()));
}
-
}
Modified: trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaEngineTest.java
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaEngineTest.java 2009-04-23
16:29:28 UTC (rev 848)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaEngineTest.java 2009-04-23
16:43:27 UTC (rev 849)
@@ -63,12 +63,13 @@
@Test
public void shouldAllowCreatingWithConfigRepository() throws InterruptedException {
- engine = new DnaConfiguration()
- .withConfigurationRepository()
- .usingClass(InMemoryRepositorySource.class)
- .describedAs("Configuration Repository")
- .with("name").setTo("config repo")
- .and().build();
+ engine = new DnaConfiguration().withConfigurationRepository()
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("Configuration
Repository")
+ .with("name")
+ .setTo("config repo")
+ .and()
+ .build();
assertThat(engine.getRepositorySource("config repo"),
is(notNullValue()));
assertThat(engine.getRepositorySource("config repo"),
is(instanceOf(InMemoryRepositorySource.class)));
@@ -84,17 +85,23 @@
@Test
public void shouldAllowCreatingMultipleRepositories() throws Exception {
- engine = new DnaConfiguration()
- .withConfigurationRepository()
- .usingClass(InMemoryRepositorySource.class)
- .describedAs("Configuration Repository")
- .with("name").setTo("config repo")
- .and().addRepository("JCR")
- .usingClass(InMemoryRepositorySource.class)
- .describedAs("Backing Repository for JCR Implementation")
- .with("name").setTo("JCR")
- .and().build();
+ engine = new DnaConfiguration().withConfigurationRepository()
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("Configuration
Repository")
+ .with("name")
+ .setTo("config repo")
+ .and()
+ .addRepository("JCR")
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("Backing Repository for JCR
Implementation")
+ .with("name")
+ .setTo("JCR")
+ .and()
+ .build();
+ // Start the engine ...
+ engine.start();
+ // Verify the components are here ...
assertThat(engine.getRepositorySource("config repo"),
is(notNullValue()));
assertThat(engine.getRepositorySource("config repo"),
is(instanceOf(InMemoryRepositorySource.class)));
@@ -111,46 +118,52 @@
@Test
public void shouldAllowAddingMimeTypeDetectors() throws Exception {
- engine = new DnaConfiguration()
- .withConfigurationRepository()
- .usingClass(InMemoryRepositorySource.class)
- .describedAs("Configuration Repository")
- .with("name").setTo("config repo")
- .and().addMimeTypeDetector("default")
- .usingClass(MockMimeTypeDetector.class)
- .describedAs("Default MimeTypeDetector")
- .with("mimeType").setTo("mock")
- .and().build();
+ engine = new DnaConfiguration().withConfigurationRepository()
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("Configuration
Repository")
+ .with("name")
+ .setTo("config repo")
+ .and()
+ .addMimeTypeDetector("default")
+ .usingClass(MockMimeTypeDetector.class)
+ .describedAs("Default
MimeTypeDetector")
+ .with("mimeType")
+ .setTo("mock")
+ .and()
+ .build();
assertThat(engine.getRepositorySource("config repo"),
is(notNullValue()));
assertThat(engine.getRepositorySource("config repo"),
is(instanceOf(InMemoryRepositorySource.class)));
RepositoryLibrary library =
engine.getRepositoryService().getRepositorySourceManager();
MimeTypeDetectors detectors = library.getMimeTypeDetectors();
-
+
assertThat(detectors.mimeTypeOf("test", new
ByteArrayInputStream("This is useless data".getBytes())),
is("mock"));
}
-
+
@Test
public void shouldAllowAddingSequencers() throws Exception {
- engine = new DnaConfiguration()
- .withConfigurationRepository()
- .usingClass(InMemoryRepositorySource.class)
- .describedAs("Configuration Repository")
- .with("name").setTo("config repo")
- .and().addSequencer("Mock Sequencer A")
- .usingClass(MockSequencerA.class)
- .describedAs("A Mock Sequencer")
- .sequencingFrom("/**").andOutputtingTo("/")
- .and().build();
+ engine = new DnaConfiguration().withConfigurationRepository()
+ .usingClass(InMemoryRepositorySource.class)
+ .describedAs("Configuration
Repository")
+ .with("name")
+ .setTo("config repo")
+ .and()
+ .addSequencer("Mock Sequencer A")
+ .usingClass(MockSequencerA.class)
+ .describedAs("A Mock Sequencer")
+ .sequencingFrom("/**")
+ .andOutputtingTo("/")
+ .and()
+ .build();
assertThat(engine.getRepositorySource("config repo"),
is(notNullValue()));
assertThat(engine.getRepositorySource("config repo"),
is(instanceOf(InMemoryRepositorySource.class)));
SequencingService sequencer = engine.getSequencingService();
assertThat(sequencer.getStatistics().getNumberOfNodesSequenced(), is(0L));
-
- NodeChanges changes = NodeChanges.create("", Arrays.asList(new Event[]
{ }));
+
+ NodeChanges changes = NodeChanges.create("", Arrays.asList(new Event[]
{}));
sequencer.onNodeChanges(changes);
assertThat(sequencer.getStatistics().getNumberOfNodesSequenced(), is(0L));
@@ -159,33 +172,32 @@
stub(e1.getType()).toReturn(Event.NODE_ADDED);
stub(e1.getPath()).toReturn("/test");
stub(e1.getUserID()).toReturn("Test");
-
-// changes = NodeChanges.create("", Arrays.asList(new Event[] { e1,
}));
-// sequencer.onNodeChanges(changes);
-//
-// // Shutdown the engine to force all pending tasks to complete
-// engine.shutdown();
-//
-// assertThat(sequencer.getStatistics().getNumberOfNodesSequenced(), is(1L));
- }
+ // changes = NodeChanges.create("", Arrays.asList(new Event[] { e1,
}));
+ // sequencer.onNodeChanges(changes);
+ //
+ // // Shutdown the engine to force all pending tasks to complete
+ // engine.shutdown();
+ //
+ // assertThat(sequencer.getStatistics().getNumberOfNodesSequenced(), is(1L));
+ }
+
public static class MockMimeTypeDetector implements MimeTypeDetector {
private String mimeType = "";
-
+
public MockMimeTypeDetector() {
-
+
}
- public void setMimeType(String mimeType) {
+ public void setMimeType( String mimeType ) {
this.mimeType = mimeType;
}
-
+
public String mimeTypeOf( String name,
InputStream is ) {
return mimeType;
}
}
-
}