Author: rhauch
Date: 2009-04-30 11:31:52 -0400 (Thu, 30 Apr 2009)
New Revision: 867
Added:
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrConfiguration.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEngine.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/NodeDefinitionId.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyId.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/Configurator.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java
Removed:
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/NodeDefinitionId.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyId.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java
Modified:
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEmptyNodeIterator.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEmptyPropertyIterator.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrLexicon.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMixLexicon.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNtLexicon.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSvLexicon.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/OnParentVersionBehavior.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SelfClosingInputStream.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaConfigurationTest.java
Log:
DNA-58 Create repository configuration and component
Refactored the DnaConfiguration class to use more interfaces and to move those interfaces
(and reusable implementations) into a Configurator class that uses generics.
DnaConfiguration instantiates a configurator, but also implements some of the high-level
interfaces by delegating them to the wrapped configurator instance. This allows
DnaConfiguration to appear to be doing the configurating, but in reality it is the wrapped
builder that is doing it. Also, DnaConfiguration (or other components) can choose which
"aspects" of configuration it is to expose by inheriting controlling which
higher-level interfaces are implemented. Since delegation is used, this works very well.
This is a more complicated design, but it is far more extensible and reusable. A
JcrConfiguration class was also created that works in the same way as DnaConfiguration,
except that it uses a different type parameter (so all the interfaces return
JcrConfiguration). It thus gets to reuse all of the Configurator logic. However,
JcrConfiguration doesn't implement all of the "aspects", essentially hiding
certain services (e.g., sequencers, since they don't yet work with our
implementation).
This change also made a few minor corrections to the JavaDoc and visibility modifiers on
the classes in the 'org.jboss.dna.jcr' package.
Added: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrConfiguration.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrConfiguration.java
(rev 0)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrConfiguration.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -0,0 +1,157 @@
+/*
+ * 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.
+ *
+ * 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.jcr;
+
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.RepositorySource;
+import org.jboss.dna.graph.mimetype.MimeTypeDetector;
+import org.jboss.dna.repository.Configurator;
+import org.jboss.dna.repository.DnaConfiguration;
+import org.jboss.dna.repository.DnaConfigurationException;
+import org.jboss.dna.repository.Configurator.ChooseClass;
+import org.jboss.dna.repository.Configurator.ConfigRepositoryDetails;
+import org.jboss.dna.repository.Configurator.MimeTypeDetectorDetails;
+import org.jboss.dna.repository.Configurator.RepositoryDetails;
+
+/**
+ * A configuration builder for a {@link JcrEngine}. This class is an internal
domain-specific language (DSL),
+ * and is designed to be used in a traditional way or in a method-chained manner:
+ * <pre>
+ *
configuration.addRepository("Source1").usingClass(InMemoryRepositorySource.class).describedAs("description");
+ * configuration.addMimeTypeDetector("detector")
+ * .usingClass(ExtensionBasedMimeTypeDetector.class)
+ * .describedAs("default detector");
+ * configuration.addSequencer("MicrosoftDocs")
+ *
.usingClass("org.jboss.dna.sequencer.msoffice.MSOfficeMetadataSequencer")
+ * .loadedFromClasspath()
+ * .named("Microsoft Document sequencer")
+ * .describedAs("Our primary sequencer for all .doc files")
+ *
.sequencingFrom("/public//(*.(doc|xml|ppt)[*]/jcr:content[@jcr:data]")
+ * .andOutputtingTo("/documents/$1");
+ * configuration.save();
+ * </pre>
+ */
+public class JcrConfiguration
+ implements Configurator.Initializer<JcrConfiguration>,
/*Configurator.SequencerConfigurator<JcrConfiguration>,*/
+ Configurator.RepositoryConfigurator<JcrConfiguration>,
Configurator.MimeDetectorConfigurator<JcrConfiguration>,
+ Configurator.Builder<JcrEngine> {
+
+ private final DnaConfiguration.Builder<JcrConfiguration> builder;
+
+ /**
+ * Create a new configuration for DNA.
+ */
+ public JcrConfiguration() {
+ this(new ExecutionContext());
+ }
+
+ /**
+ * 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 JcrConfiguration( ExecutionContext context ) {
+ this.builder = new DnaConfiguration.Builder<JcrConfiguration>(context,
this);
+ }
+
+ /**
+ * Get the execution context used by this configurator.
+ *
+ * @return the execution context; never null
+ */
+ public final ExecutionContext getExecutionContext() {
+ return builder.getExecutionContext();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.Initializer#withConfigurationRepository()
+ */
+ public ChooseClass<RepositorySource,
ConfigRepositoryDetails<JcrConfiguration>> withConfigurationRepository() {
+ return builder.withConfigurationRepository();
+ }
+
+// /**
+// * {@inheritDoc}
+// *
+// * @see
org.jboss.dna.repository.Configurator.SequencerConfigurator#addSequencer(java.lang.String)
+// */
+// public ChooseClass<Sequencer, SequencerDetails<JcrConfiguration>>
addSequencer( String id ) {
+// CheckArg.isNotEmpty(id, "id");
+// return builder.addSequencer(id);
+// }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.RepositoryConfigurator#addRepository(java.lang.String)
+ */
+ public ChooseClass<RepositorySource, RepositoryDetails<JcrConfiguration>>
addRepository( String id ) {
+ CheckArg.isNotEmpty(id, "id");
+ return builder.addRepository(id);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.RepositoryConfigurator#addRepository(org.jboss.dna.graph.connector.RepositorySource)
+ */
+ public JcrConfiguration addRepository( RepositorySource source ) {
+ CheckArg.isNotNull(source, "source");
+ CheckArg.isNotEmpty(source.getName(), "source.getName()");
+ return builder.addRepository(source);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.MimeDetectorConfigurator#addMimeTypeDetector(java.lang.String)
+ */
+ public ChooseClass<MimeTypeDetector,
MimeTypeDetectorDetails<JcrConfiguration>> addMimeTypeDetector( String id ) {
+ CheckArg.isNotEmpty(id, "id");
+ return builder.addMimeTypeDetector(id);
+ }
+
+ /**
+ * Save any changes that have been made so far to the configuration. This method does
nothing if no changes have been made.
+ *
+ * @return this configuration object for method chaining purposes; never null
+ */
+ public JcrConfiguration save() {
+ return builder.save();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator.Builder#build()
+ */
+ public JcrEngine build() throws DnaConfigurationException {
+ save();
+ return new JcrEngine(builder.buildDnaEngine());
+ }
+}
Property changes on: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrConfiguration.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEmptyNodeIterator.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEmptyNodeIterator.java 2009-04-30
04:32:26 UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEmptyNodeIterator.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -31,7 +31,7 @@
/**
*
*/
-public class JcrEmptyNodeIterator implements NodeIterator {
+class JcrEmptyNodeIterator implements NodeIterator {
/**
* {@inheritDoc}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEmptyPropertyIterator.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEmptyPropertyIterator.java 2009-04-30
04:32:26 UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEmptyPropertyIterator.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -31,7 +31,7 @@
/**
*
*/
-public class JcrEmptyPropertyIterator implements PropertyIterator {
+class JcrEmptyPropertyIterator implements PropertyIterator {
/**
* {@inheritDoc}
Added: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEngine.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEngine.java
(rev 0)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEngine.java 2009-04-30 15:31:52 UTC
(rev 867)
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ *
+ * 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.jcr;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import org.jboss.dna.common.collection.Problems;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
+import org.jboss.dna.graph.connector.RepositorySource;
+import org.jboss.dna.jcr.JcrRepository.Options;
+import org.jboss.dna.repository.DnaEngine;
+import org.jboss.dna.repository.RepositoryService;
+import org.jboss.dna.repository.observation.ObservationService;
+import org.jboss.dna.repository.sequencer.SequencingService;
+
+/**
+ * The basic component that encapsulates the JBoss DNA services, including the {@link
Repository} instances.
+ */
+public class JcrEngine {
+
+ private final DnaEngine dnaEngine;
+ private final Map<String, JcrRepository> repositories;
+ private final Lock repositoriesLock;
+
+ JcrEngine( DnaEngine dnaEngine ) {
+ this.dnaEngine = dnaEngine;
+ this.repositories = new HashMap<String, JcrRepository>();
+ this.repositoriesLock = new ReentrantLock();
+ }
+
+ /**
+ * 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 dnaEngine.getProblems();
+ }
+
+ /**
+ * Get the execution context for this engine. This context can be used to create
additional (perhaps narrowed) contexts.
+ *
+ * @return the engine's execution context; never null
+ */
+ public final ExecutionContext getExecutionContext() {
+ return dnaEngine.getExecutionContext();
+ }
+
+ /**
+ * Get the RepositorySource with the supplied name.
+ *
+ * @param repositoryName the name of the repository (or repository source)
+ * @return the named repository source, or null if there is no such repository
+ */
+ protected final RepositorySource getRepositorySource( String repositoryName ) {
+ return dnaEngine.getRepositorySource(repositoryName);
+ }
+
+ protected final RepositoryConnectionFactory getRepositoryConnectionFactory() {
+ return dnaEngine.getRepositoryConnectionFactory();
+ }
+
+ protected final RepositoryService getRepositoryService() {
+ return dnaEngine.getRepositoryService();
+ }
+
+ protected final ObservationService getObservationService() {
+ return dnaEngine.getObservationService();
+ }
+
+ protected final SequencingService getSequencingService() {
+ return dnaEngine.getSequencingService();
+ }
+
+ /**
+ * Get the {@link Repository} implementation for the named repository.
+ *
+ * @param repositoryName the name of the repository, which corresponds to the name of
a configured {@link RepositorySource}
+ * @return the named repository instance
+ * @throws IllegalArgumentException if the repository name is null, blank or invalid
+ * @throws RepositoryException if there is no repository with the specified name
+ */
+ public final Repository getRepository( String repositoryName ) throws
RepositoryException {
+ CheckArg.isNotEmpty(repositoryName, "repositoryName");
+ try {
+ repositoriesLock.lock();
+ JcrRepository repository = repositories.get(repositoryName);
+ if (repository == null) {
+ if (getRepositorySource(repositoryName) == null) {
+ // The repository name is not a valid repository ...
+ String msg = JcrI18n.repositoryDoesNotExist.text(repositoryName);
+ throw new RepositoryException(msg);
+ }
+ repository = doCreateJcrRepository(repositoryName);
+ repositories.put(repositoryName, repository);
+ }
+ return repository;
+ } finally {
+ repositoriesLock.unlock();
+ }
+ }
+
+ protected JcrRepository doCreateJcrRepository( String repositoryName ) {
+ RepositoryConnectionFactory connectionFactory =
getRepositoryConnectionFactory();
+ Map<String, String> descriptors = null;
+ Map<Options, String> options =
Collections.singletonMap(Options.PROJECT_NODE_TYPES, "false");
+ return new JcrRepository(getExecutionContext(), connectionFactory,
repositoryName, descriptors, options);
+ }
+
+ /*
+ * Lifecycle methods
+ */
+
+ public void start() {
+ dnaEngine.start();
+ }
+
+ public void shutdown() {
+ dnaEngine.shutdown();
+ }
+}
Property changes on: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrEngine.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java 2009-04-30 04:32:26 UTC
(rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java 2009-04-30 15:31:52 UTC
(rev 867)
@@ -43,6 +43,7 @@
public static I18n permissionDenied;
public static I18n repositoryMustBeConfigured;
public static I18n sourceInUse;
+ public static I18n repositoryDoesNotExist;
public static I18n noNamespaceWithPrefix;
public static I18n noNamespaceWithUri;
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrLexicon.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrLexicon.java 2009-04-30 04:32:26 UTC
(rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrLexicon.java 2009-04-30 15:31:52 UTC
(rev 867)
@@ -27,9 +27,9 @@
import org.jboss.dna.graph.property.basic.BasicName;
/**
- * @author Randall Hauch
+ * Lexicon of names from the standard JCR
"<code>http://www.jcp.org/jcr/1.0</code>" namespace.
*/
-class JcrLexicon extends org.jboss.dna.graph.JcrLexicon {
+public class JcrLexicon extends org.jboss.dna.graph.JcrLexicon {
public static final Name BASE_VERSION = new BasicName(Namespace.URI,
"baseVersion");
public static final Name CONTENT = new BasicName(Namespace.URI,
"content");
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMixLexicon.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMixLexicon.java 2009-04-30 04:32:26
UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMixLexicon.java 2009-04-30 15:31:52
UTC (rev 867)
@@ -1,5 +1,31 @@
+/*
+ * 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.jcr;
+/**
+ * Lexicon of names from the standard JCR
"<code>http://www.jcp.org/jcr/mix/1.0</code>" namespace.
+ */
public class JcrMixLexicon extends org.jboss.dna.graph.JcrMixLexicon {
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java 2009-04-30
04:32:26 UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrMultiValueProperty.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -40,7 +40,7 @@
import org.jboss.dna.graph.property.Property;
/**
- * @author jverhaeg
+ *
*/
@NotThreadSafe
final class JcrMultiValueProperty extends AbstractJcrProperty {
@@ -222,7 +222,7 @@
} else {
jcrValues = EMPTY_VALUES;
}
-
+
cache.getEditorFor(propertyId.getNodeId()).setProperty(propertyId.getPropertyName(),
jcrValues, PropertyType.STRING);
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java 2009-04-30 04:32:26 UTC
(rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNode.java 2009-04-30 15:31:52 UTC
(rev 867)
@@ -30,7 +30,7 @@
import net.jcip.annotations.NotThreadSafe;
/**
- * @author jverhaeg
+ *
*/
@NotThreadSafe
final class JcrNode extends AbstractJcrNode {
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNtLexicon.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNtLexicon.java 2009-04-30 04:32:26
UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrNtLexicon.java 2009-04-30 15:31:52
UTC (rev 867)
@@ -26,6 +26,9 @@
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.basic.BasicName;
+/**
+ * Lexicon of names from the standard JCR
"<code>http://www.jcp.org/jcr/nt/1.0</code>" namespace.
+ */
public class JcrNtLexicon extends org.jboss.dna.graph.JcrNtLexicon {
public static final Name FROZEN_NODE = new BasicName(Namespace.URI,
"frozenNode");
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java 2009-04-30
04:32:26 UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSingleValueProperty.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -39,7 +39,7 @@
import org.jboss.dna.graph.property.ValueFactories;
/**
- * @author jverhaeg
+ *
*/
final class JcrSingleValueProperty extends AbstractJcrProperty {
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSvLexicon.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSvLexicon.java 2009-04-30 04:32:26
UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrSvLexicon.java 2009-04-30 15:31:52
UTC (rev 867)
@@ -27,7 +27,7 @@
import org.jboss.dna.graph.property.basic.BasicName;
/**
- *
+ * Lexicon of names from the standard JCR
"<code>http://www.jcp.org/jcr/sv/1.0</code>" namespace.
*/
public class JcrSvLexicon {
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java 2009-04-30 04:32:26 UTC
(rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrValue.java 2009-04-30 15:31:52 UTC
(rev 867)
@@ -45,7 +45,7 @@
import org.jboss.dna.graph.property.ValueFactories;
/**
- * @author jverhaeg
+ *
*/
@NotThreadSafe
final class JcrValue implements Value {
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-04-30 04:32:26
UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-04-30 15:31:52
UTC (rev 867)
@@ -68,8 +68,7 @@
import org.xml.sax.helpers.XMLReaderFactory;
/**
- * @author John Verhaeg
- * @author Randall Hauch
+ *
*/
@NotThreadSafe
final class JcrWorkspace implements Workspace {
Deleted: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/NodeDefinitionId.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/NodeDefinitionId.java 2009-04-30
04:32:26 UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/NodeDefinitionId.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -1,201 +0,0 @@
-/*
- * 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.
- *
- * 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.jcr;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import net.jcip.annotations.Immutable;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.NameFactory;
-import org.jboss.dna.graph.property.ValueFormatException;
-
-/**
- * An immutable identifier for a node definition. Although instances can be serialized,
the node definitions are often stored
- * within the graph as {@link #getString() string values} on a property. These string
values can later be
- * {@link #fromString(String, NameFactory) parsed} to reconstruct the identifier. Note
that this string representation does not
- * use namespace prefixes, so they are long-lasting and durable.
- * <p>
- * What distinguishes one property definition from another is not well documented in the
JSR-170 specification. The closest this
- * version of the spec gets is Section 6.7.15, but that merely says that more than one
property definition can have the same name.
- * The proposed draft of the JSR-283 specification does clarify this more: Section 4.7.15
says :
- * </p>
- * <p>
- * <quote>"Similarly, a node type may have two or more child node definitions
with identical name attributes as long as they are
- * distinguishable by the required primary types attribute (the value returned by
- * NodeDefinition.getRequiredPrimaryTypes)."</quote>
- * </p>
- * <p>
- * This class is {@link Serializable} and designed to be used as a key in a {@link
HashMap}.
- * </p>
- */
-@Immutable
-public final class NodeDefinitionId implements Serializable {
-
- /**
- * Current version is {@value} .
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * The string-form of the name that can be used to represent a residual property
definition.
- */
- public static final String ANY_NAME = JcrNodeType.RESIDUAL_ITEM_NAME;
-
- private final Name nodeTypeName;
- private final Name childDefinitionName;
- private final Name[] requiredPrimaryTypes;
- /**
- * A cached string representation, which is used for {@link #equals(Object)} and
{@link #hashCode()} among other things.
- */
- private final String stringRepresentation;
-
- /**
- * Create an identifier for a node definition.
- *
- * @param nodeTypeName the name of the node type on which this child node definition
is defined; may not be null
- * @param childDefinitionName the name of the child node definition, which may be a
{@link #ANY_NAME residual child
- * definition}; may not be null
- * @param requiredPrimaryTypes the names of the required primary types for the child
node definition
- */
- public NodeDefinitionId( Name nodeTypeName,
- Name childDefinitionName,
- Name[] requiredPrimaryTypes ) {
- assert nodeTypeName != null;
- assert childDefinitionName != null;
- this.nodeTypeName = nodeTypeName;
- this.childDefinitionName = childDefinitionName;
- this.requiredPrimaryTypes = requiredPrimaryTypes;
- StringBuilder sb = new StringBuilder(this.nodeTypeName.getString());
- sb.append('/').append(this.childDefinitionName.getString());
- for (Name requiredPrimaryType : requiredPrimaryTypes) {
- sb.append('/');
- sb.append(requiredPrimaryType.getString());
- }
- this.stringRepresentation = sb.toString();
- }
-
- /**
- * Get the name of the node type on which the child node definition is defined.
- *
- * @return the node type's name; never null
- */
- public Name getNodeTypeName() {
- return nodeTypeName;
- }
-
- /**
- * Get the name of the child definition.
- *
- * @return the child definition's name; never null
- */
- public Name getChildDefinitionName() {
- return childDefinitionName;
- }
-
- /**
- * @return requiredPrimaryTypes
- */
- public Name[] getRequiredPrimaryTypes() {
- Name[] copy = new Name[requiredPrimaryTypes.length];
- System.arraycopy(requiredPrimaryTypes, 0, copy, 0, requiredPrimaryTypes.length);
- return copy;
- }
-
- /**
- * Determine whether this node definition defines any named child.
- *
- * @return true if this node definition allows children with any name, or false if
this definition requires a particular child
- * name
- */
- public boolean allowsAnyChildName() {
- return childDefinitionName.getLocalName().equals(ANY_NAME) &&
childDefinitionName.getNamespaceUri().length() == 0;
- }
-
- /**
- * Get the string form of this identifier. This form can be persisted, since it does
not rely upon namespace prefixes.
- *
- * @return the string form
- */
- public String getString() {
- return this.stringRepresentation;
- }
-
- /**
- * Parse the supplied string for of an identifer, and return the object form for that
identifier.
- *
- * @param definition the {@link #getString() string form of the identifier}; may not
be null
- * @param factory the factory that should be used to create Name objects; may not be
null
- * @return the object form of the identifier; never null
- * @throws ValueFormatException if the definition is not the valid format
- */
- public static NodeDefinitionId fromString( String definition,
- NameFactory factory ) {
- String[] parts = definition.split("/");
- String nodeTypeNameString = parts[0];
- String childDefinitionNameString = parts[1];
- Name[] requiredPrimaryTypes = new Name[parts.length - 2];
- for (int i = 2, j = 0; i != parts.length; ++i, ++j) {
- requiredPrimaryTypes[j] = factory.create(parts[i]);
- }
- Name nodeTypeName = factory.create(nodeTypeNameString);
- Name childDefinitionName = factory.create(childDefinitionNameString);
- return new NodeDefinitionId(nodeTypeName, childDefinitionName,
requiredPrimaryTypes);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return stringRepresentation.hashCode();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals( Object obj ) {
- if (obj == this) return true;
- if (obj instanceof NodeDefinitionId) {
- NodeDefinitionId that = (NodeDefinitionId)obj;
- return this.stringRepresentation.equals(that.stringRepresentation);
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return this.stringRepresentation;
- }
-
-}
Added: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/NodeDefinitionId.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/NodeDefinitionId.java
(rev 0)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/NodeDefinitionId.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ *
+ * 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.jcr;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NameFactory;
+import org.jboss.dna.graph.property.ValueFormatException;
+
+/**
+ * An immutable identifier for a node definition. Although instances can be serialized,
the node definitions are often stored
+ * within the graph as {@link #getString() string values} on a property. These string
values can later be
+ * {@link #fromString(String, NameFactory) parsed} to reconstruct the identifier. Note
that this string representation does not
+ * use namespace prefixes, so they are long-lasting and durable.
+ * <p>
+ * What distinguishes one property definition from another is not well documented in the
JSR-170 specification. The closest this
+ * version of the spec gets is Section 6.7.15, but that merely says that more than one
property definition can have the same name.
+ * The proposed draft of the JSR-283 specification does clarify this more: Section 4.7.15
says :
+ * </p>
+ * <p>
+ * <quote>"Similarly, a node type may have two or more child node definitions
with identical name attributes as long as they are
+ * distinguishable by the required primary types attribute (the value returned by
+ * NodeDefinition.getRequiredPrimaryTypes)."</quote>
+ * </p>
+ * <p>
+ * This class is {@link Serializable} and designed to be used as a key in a {@link
HashMap}.
+ * </p>
+ */
+@Immutable
+public final class NodeDefinitionId implements Serializable {
+
+ /**
+ * Current version is {@value} .
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The string-form of the name that can be used to represent a residual property
definition.
+ */
+ public static final String ANY_NAME = JcrNodeType.RESIDUAL_ITEM_NAME;
+
+ private final Name nodeTypeName;
+ private final Name childDefinitionName;
+ private final Name[] requiredPrimaryTypes;
+ /**
+ * A cached string representation, which is used for {@link #equals(Object)} and
{@link #hashCode()} among other things.
+ */
+ private final String stringRepresentation;
+
+ /**
+ * Create an identifier for a node definition.
+ *
+ * @param nodeTypeName the name of the node type on which this child node definition
is defined; may not be null
+ * @param childDefinitionName the name of the child node definition, which may be a
{@link #ANY_NAME residual child
+ * definition}; may not be null
+ * @param requiredPrimaryTypes the names of the required primary types for the child
node definition
+ */
+ public NodeDefinitionId( Name nodeTypeName,
+ Name childDefinitionName,
+ Name[] requiredPrimaryTypes ) {
+ assert nodeTypeName != null;
+ assert childDefinitionName != null;
+ this.nodeTypeName = nodeTypeName;
+ this.childDefinitionName = childDefinitionName;
+ this.requiredPrimaryTypes = requiredPrimaryTypes;
+ StringBuilder sb = new StringBuilder(this.nodeTypeName.getString());
+ sb.append('/').append(this.childDefinitionName.getString());
+ for (Name requiredPrimaryType : requiredPrimaryTypes) {
+ sb.append('/');
+ sb.append(requiredPrimaryType.getString());
+ }
+ this.stringRepresentation = sb.toString();
+ }
+
+ /**
+ * Get the name of the node type on which the child node definition is defined.
+ *
+ * @return the node type's name; never null
+ */
+ public Name getNodeTypeName() {
+ return nodeTypeName;
+ }
+
+ /**
+ * Get the name of the child definition.
+ *
+ * @return the child definition's name; never null
+ */
+ public Name getChildDefinitionName() {
+ return childDefinitionName;
+ }
+
+ /**
+ * @return requiredPrimaryTypes
+ */
+ public Name[] getRequiredPrimaryTypes() {
+ Name[] copy = new Name[requiredPrimaryTypes.length];
+ System.arraycopy(requiredPrimaryTypes, 0, copy, 0, requiredPrimaryTypes.length);
+ return copy;
+ }
+
+ /**
+ * Determine whether this node definition defines any named child.
+ *
+ * @return true if this node definition allows children with any name, or false if
this definition requires a particular child
+ * name
+ */
+ public boolean allowsAnyChildName() {
+ return childDefinitionName.getLocalName().equals(ANY_NAME) &&
childDefinitionName.getNamespaceUri().length() == 0;
+ }
+
+ /**
+ * Get the string form of this identifier. This form can be persisted, since it does
not rely upon namespace prefixes.
+ *
+ * @return the string form
+ */
+ public String getString() {
+ return this.stringRepresentation;
+ }
+
+ /**
+ * Parse the supplied string for of an identifer, and return the object form for that
identifier.
+ *
+ * @param definition the {@link #getString() string form of the identifier}; may not
be null
+ * @param factory the factory that should be used to create Name objects; may not be
null
+ * @return the object form of the identifier; never null
+ * @throws ValueFormatException if the definition is not the valid format
+ */
+ public static NodeDefinitionId fromString( String definition,
+ NameFactory factory ) {
+ String[] parts = definition.split("/");
+ String nodeTypeNameString = parts[0];
+ String childDefinitionNameString = parts[1];
+ Name[] requiredPrimaryTypes = new Name[parts.length - 2];
+ for (int i = 2, j = 0; i != parts.length; ++i, ++j) {
+ requiredPrimaryTypes[j] = factory.create(parts[i]);
+ }
+ Name nodeTypeName = factory.create(nodeTypeNameString);
+ Name childDefinitionName = factory.create(childDefinitionNameString);
+ return new NodeDefinitionId(nodeTypeName, childDefinitionName,
requiredPrimaryTypes);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return stringRepresentation.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof NodeDefinitionId) {
+ NodeDefinitionId that = (NodeDefinitionId)obj;
+ return this.stringRepresentation.equals(that.stringRepresentation);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return this.stringRepresentation;
+ }
+
+}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/OnParentVersionBehavior.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/OnParentVersionBehavior.java 2009-04-30
04:32:26 UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/OnParentVersionBehavior.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -28,7 +28,7 @@
/**
* Enumeration of possible behaviors for on-parent-version setting of properties and
child nodes in JCR specification.
*/
-public enum OnParentVersionBehavior {
+enum OnParentVersionBehavior {
/** @see OnParentVersionAction#ABORT */
ABORT(OnParentVersionAction.ABORT, OnParentVersionAction.ACTIONNAME_ABORT),
/** @see OnParentVersionAction#COMPUTE */
Deleted: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java 2009-04-30
04:32:26 UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -1,216 +0,0 @@
-/*
- * 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.
- *
- * 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.jcr;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import javax.jcr.PropertyType;
-import net.jcip.annotations.Immutable;
-import org.jboss.dna.graph.property.Name;
-import org.jboss.dna.graph.property.NameFactory;
-import org.jboss.dna.graph.property.ValueFormatException;
-
-/**
- * An immutable identifier for a property definition. Although instances can be
serialized, the property definitions are often
- * stored within the graph as {@link #getString() string values} on a property. These
string values can later be
- * {@link #fromString(String, NameFactory) parsed} to reconstruct the identifier. Note
that this string representation does not
- * use namespace prefixes, so they are long-lasting and durable.
- * <p>
- * What distinguishes one property definition from another is not well documented in the
JSR-170 specification. The closest this
- * version of the spec gets is Section 6.7.15, but that merely says that more than one
property definition can have the same name.
- * The proposed draft of the JSR-283 specification does clarify this more: Section 4.7.15
says :
- * </p>
- * <p>
- * <quote>"A node type may have two or more property definitions with
identical name attributes (the value returned by
- * ItemDefinition.getName) as long as the definitions are otherwise distinguishable by
either the required type attribute (the
- * value returned by PropertyDefinition.getRequiredType) or the multiple attribute (the
value returned by
- * PropertyDefinition.isMultiple)."</quote>
- * </p>
- * <p>
- * This class is {@link Serializable} and designed to be used as a key in a {@link
HashMap}.
- * </p>
- */
-@Immutable
-public final class PropertyDefinitionId implements Serializable {
-
- /**
- * Current version is {@value} .
- */
- private static final long serialVersionUID = 1L;
-
- /**
- * The string-form of the name that can be used to represent a residual property
definition.
- */
- public static final String ANY_NAME = JcrNodeType.RESIDUAL_ITEM_NAME;
-
- private final Name nodeTypeName;
- private final Name propertyDefinitionName;
- private final int propertyType;
- private final boolean allowsMultiple;
- /**
- * A cached string representation, which is used for {@link #equals(Object)} and
{@link #hashCode()} among other things.
- */
- private final String stringRepresentation;
-
- /**
- * Create a new identifier for a property definition.
- *
- * @param nodeTypeName the name of the node type; may not be null
- * @param propertyDefinitionName the name of the property definition, which may be a
{@link #ANY_NAME residual property}; may
- * not be null
- * @param propertyType the required property type for the definition; must be a valid
{@link PropertyType} value
- * @param allowsMultiple true if the property definition should allow multiple
values, or false if it is a single-value
- * property definition
- */
- public PropertyDefinitionId( Name nodeTypeName,
- Name propertyDefinitionName,
- int propertyType,
- boolean allowsMultiple ) {
- this.nodeTypeName = nodeTypeName;
- this.propertyDefinitionName = propertyDefinitionName;
- this.propertyType = propertyType;
- this.allowsMultiple = allowsMultiple;
- this.stringRepresentation = this.nodeTypeName.getString() + '/' +
this.propertyDefinitionName.getString() + '/'
- + PropertyType.nameFromValue(propertyType) +
'/' + (allowsMultiple ? '*' : '1');
- }
-
- /**
- * Get the name of the node type on which the property definition is defined
- *
- * @return the node type's name; may not be null
- */
- public Name getNodeTypeName() {
- return nodeTypeName;
- }
-
- /**
- * Get the name of the property definition.
- *
- * @return the property definition's name; never null
- */
- public Name getPropertyDefinitionName() {
- return propertyDefinitionName;
- }
-
- /**
- * Get the required property type
- *
- * @return the property type; always a valid {@link PropertyType} value
- */
- public int getPropertyType() {
- return propertyType;
- }
-
- /**
- * Return whether the property definition allows multiple values.
- *
- * @return true if the property definition allows multiple values, or false if it is
a single-value property definition
- */
- public boolean allowsMultiple() {
- return allowsMultiple;
- }
-
- /**
- * Determine whether this property definition allows properties with any name.
- *
- * @return true if this node definition allows properties with any name, or false if
this definition requires a particular
- * property name
- */
- public boolean allowsAnyChildName() {
- return propertyDefinitionName.getLocalName().equals(ANY_NAME) &&
propertyDefinitionName.getNamespaceUri().length() == 0;
- }
-
- /**
- * Get the string form of this identifier. This form can be persisted, since it does
not rely upon namespace prefixes.
- *
- * @return the string form
- */
- public String getString() {
- return this.stringRepresentation;
- }
-
- /**
- * Parse the supplied string for of an identifer, and return the object form for that
identifier.
- *
- * @param definition the {@link #getString() string form of the identifier}; may not
be null
- * @param factory the factory that should be used to create Name objects; may not be
null
- * @return the object form of the identifier; never null
- * @throws ValueFormatException if the definition is not the valid format
- */
- public static PropertyDefinitionId fromString( String definition,
- NameFactory factory ) {
- String[] parts = definition.split("/");
- String nodeTypeNameString = parts[0];
- String propertyDefinitionNameString = parts[1];
- Name nodeTypeName = factory.create(nodeTypeNameString);
- Name propertyDefinitionName = factory.create(propertyDefinitionNameString);
- int propertyType = PropertyType.valueFromName(parts[2]);
- boolean allowsMultiple = parts[3].charAt(0) == '*';
- return new PropertyDefinitionId(nodeTypeName, propertyDefinitionName,
propertyType, allowsMultiple);
- }
-
- public PropertyDefinitionId asSingleValued() {
- return new PropertyDefinitionId(nodeTypeName, propertyDefinitionName,
propertyType, false);
- }
-
- public PropertyDefinitionId asMultiValued() {
- return new PropertyDefinitionId(nodeTypeName, propertyDefinitionName,
propertyType, true);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return this.stringRepresentation.hashCode();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals( Object obj ) {
- if (obj == this) return true;
- if (obj instanceof PropertyDefinitionId) {
- PropertyDefinitionId that = (PropertyDefinitionId)obj;
- return this.stringRepresentation.equals(that.stringRepresentation);
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return this.stringRepresentation;
- }
-
-}
Added: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java
(rev 0)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyDefinitionId.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ *
+ * 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.jcr;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import javax.jcr.PropertyType;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.NameFactory;
+import org.jboss.dna.graph.property.ValueFormatException;
+
+/**
+ * An immutable identifier for a property definition. Although instances can be
serialized, the property definitions are often
+ * stored within the graph as {@link #getString() string values} on a property. These
string values can later be
+ * {@link #fromString(String, NameFactory) parsed} to reconstruct the identifier. Note
that this string representation does not
+ * use namespace prefixes, so they are long-lasting and durable.
+ * <p>
+ * What distinguishes one property definition from another is not well documented in the
JSR-170 specification. The closest this
+ * version of the spec gets is Section 6.7.15, but that merely says that more than one
property definition can have the same name.
+ * The proposed draft of the JSR-283 specification does clarify this more: Section 4.7.15
says :
+ * </p>
+ * <p>
+ * <quote>"A node type may have two or more property definitions with
identical name attributes (the value returned by
+ * ItemDefinition.getName) as long as the definitions are otherwise distinguishable by
either the required type attribute (the
+ * value returned by PropertyDefinition.getRequiredType) or the multiple attribute (the
value returned by
+ * PropertyDefinition.isMultiple)."</quote>
+ * </p>
+ * <p>
+ * This class is {@link Serializable} and designed to be used as a key in a {@link
HashMap}.
+ * </p>
+ */
+@Immutable
+public final class PropertyDefinitionId implements Serializable {
+
+ /**
+ * Current version is {@value} .
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * The string-form of the name that can be used to represent a residual property
definition.
+ */
+ public static final String ANY_NAME = JcrNodeType.RESIDUAL_ITEM_NAME;
+
+ private final Name nodeTypeName;
+ private final Name propertyDefinitionName;
+ private final int propertyType;
+ private final boolean allowsMultiple;
+ /**
+ * A cached string representation, which is used for {@link #equals(Object)} and
{@link #hashCode()} among other things.
+ */
+ private final String stringRepresentation;
+
+ /**
+ * Create a new identifier for a property definition.
+ *
+ * @param nodeTypeName the name of the node type; may not be null
+ * @param propertyDefinitionName the name of the property definition, which may be a
{@link #ANY_NAME residual property}; may
+ * not be null
+ * @param propertyType the required property type for the definition; must be a valid
{@link PropertyType} value
+ * @param allowsMultiple true if the property definition should allow multiple
values, or false if it is a single-value
+ * property definition
+ */
+ public PropertyDefinitionId( Name nodeTypeName,
+ Name propertyDefinitionName,
+ int propertyType,
+ boolean allowsMultiple ) {
+ this.nodeTypeName = nodeTypeName;
+ this.propertyDefinitionName = propertyDefinitionName;
+ this.propertyType = propertyType;
+ this.allowsMultiple = allowsMultiple;
+ this.stringRepresentation = this.nodeTypeName.getString() + '/' +
this.propertyDefinitionName.getString() + '/'
+ + PropertyType.nameFromValue(propertyType) +
'/' + (allowsMultiple ? '*' : '1');
+ }
+
+ /**
+ * Get the name of the node type on which the property definition is defined
+ *
+ * @return the node type's name; may not be null
+ */
+ public Name getNodeTypeName() {
+ return nodeTypeName;
+ }
+
+ /**
+ * Get the name of the property definition.
+ *
+ * @return the property definition's name; never null
+ */
+ public Name getPropertyDefinitionName() {
+ return propertyDefinitionName;
+ }
+
+ /**
+ * Get the required property type
+ *
+ * @return the property type; always a valid {@link PropertyType} value
+ */
+ public int getPropertyType() {
+ return propertyType;
+ }
+
+ /**
+ * Return whether the property definition allows multiple values.
+ *
+ * @return true if the property definition allows multiple values, or false if it is
a single-value property definition
+ */
+ public boolean allowsMultiple() {
+ return allowsMultiple;
+ }
+
+ /**
+ * Determine whether this property definition allows properties with any name.
+ *
+ * @return true if this node definition allows properties with any name, or false if
this definition requires a particular
+ * property name
+ */
+ public boolean allowsAnyChildName() {
+ return propertyDefinitionName.getLocalName().equals(ANY_NAME) &&
propertyDefinitionName.getNamespaceUri().length() == 0;
+ }
+
+ /**
+ * Get the string form of this identifier. This form can be persisted, since it does
not rely upon namespace prefixes.
+ *
+ * @return the string form
+ */
+ public String getString() {
+ return this.stringRepresentation;
+ }
+
+ /**
+ * Parse the supplied string for of an identifer, and return the object form for that
identifier.
+ *
+ * @param definition the {@link #getString() string form of the identifier}; may not
be null
+ * @param factory the factory that should be used to create Name objects; may not be
null
+ * @return the object form of the identifier; never null
+ * @throws ValueFormatException if the definition is not the valid format
+ */
+ public static PropertyDefinitionId fromString( String definition,
+ NameFactory factory ) {
+ String[] parts = definition.split("/");
+ String nodeTypeNameString = parts[0];
+ String propertyDefinitionNameString = parts[1];
+ Name nodeTypeName = factory.create(nodeTypeNameString);
+ Name propertyDefinitionName = factory.create(propertyDefinitionNameString);
+ int propertyType = PropertyType.valueFromName(parts[2]);
+ boolean allowsMultiple = parts[3].charAt(0) == '*';
+ return new PropertyDefinitionId(nodeTypeName, propertyDefinitionName,
propertyType, allowsMultiple);
+ }
+
+ public PropertyDefinitionId asSingleValued() {
+ return new PropertyDefinitionId(nodeTypeName, propertyDefinitionName,
propertyType, false);
+ }
+
+ public PropertyDefinitionId asMultiValued() {
+ return new PropertyDefinitionId(nodeTypeName, propertyDefinitionName,
propertyType, true);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return this.stringRepresentation.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof PropertyDefinitionId) {
+ PropertyDefinitionId that = (PropertyDefinitionId)obj;
+ return this.stringRepresentation.equals(that.stringRepresentation);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return this.stringRepresentation;
+ }
+
+}
Deleted: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyId.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyId.java 2009-04-30 04:32:26 UTC
(rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyId.java 2009-04-30 15:31:52 UTC
(rev 867)
@@ -1,111 +0,0 @@
-/*
- * 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.
- *
- * 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.jcr;
-
-import java.util.UUID;
-import net.jcip.annotations.Immutable;
-import org.jboss.dna.common.util.HashCode;
-import org.jboss.dna.graph.property.Name;
-
-/**
- * An immutable identifier for a property, often used to reference information a property
held within the {@link SessionCache}.
- */
-@Immutable
-public final class PropertyId {
-
- private final UUID nodeId;
- private final Name propertyName;
- private final int hc;
-
- /**
- * Create a new property identifier.
- *
- * @param nodeId the UUID of the node that owns the property being reference; may not
be null
- * @param propertyName the name of the property being referenced; may not be null
- */
- public PropertyId( UUID nodeId,
- Name propertyName ) {
- assert nodeId != null;
- assert propertyName != null;
- this.nodeId = nodeId;
- this.propertyName = propertyName;
- this.hc = HashCode.compute(this.nodeId, this.propertyName);
- }
-
- /**
- * Get the UUID of the node that owns the property.
- *
- * @return the node's UUID; never null
- */
- public UUID getNodeId() {
- return nodeId;
- }
-
- /**
- * Get the name of the property.
- *
- * @return the property name; never null
- */
- public Name getPropertyName() {
- return propertyName;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#hashCode()
- */
- @Override
- public int hashCode() {
- return hc;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#equals(java.lang.Object)
- */
- @Override
- public boolean equals( Object obj ) {
- if (obj == this) return true;
- if (obj instanceof PropertyId) {
- PropertyId that = (PropertyId)obj;
- if (this.hc != that.hc) return false;
- if (!this.nodeId.equals(that.nodeId)) return false;
- return this.propertyName.equals(that.propertyName);
- }
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return this.nodeId.toString() + '@' + this.propertyName.toString();
- }
-
-}
Added: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyId.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyId.java
(rev 0)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/PropertyId.java 2009-04-30 15:31:52 UTC
(rev 867)
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ *
+ * 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.jcr;
+
+import java.util.UUID;
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.common.util.HashCode;
+import org.jboss.dna.graph.property.Name;
+
+/**
+ * An immutable identifier for a property, often used to reference information a property
held within the {@link SessionCache}.
+ */
+@Immutable
+public final class PropertyId {
+
+ private final UUID nodeId;
+ private final Name propertyName;
+ private final int hc;
+
+ /**
+ * Create a new property identifier.
+ *
+ * @param nodeId the UUID of the node that owns the property being reference; may not
be null
+ * @param propertyName the name of the property being referenced; may not be null
+ */
+ public PropertyId( UUID nodeId,
+ Name propertyName ) {
+ assert nodeId != null;
+ assert propertyName != null;
+ this.nodeId = nodeId;
+ this.propertyName = propertyName;
+ this.hc = HashCode.compute(this.nodeId, this.propertyName);
+ }
+
+ /**
+ * Get the UUID of the node that owns the property.
+ *
+ * @return the node's UUID; never null
+ */
+ public UUID getNodeId() {
+ return nodeId;
+ }
+
+ /**
+ * Get the name of the property.
+ *
+ * @return the property name; never null
+ */
+ public Name getPropertyName() {
+ return propertyName;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ return hc;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals( Object obj ) {
+ if (obj == this) return true;
+ if (obj instanceof PropertyId) {
+ PropertyId that = (PropertyId)obj;
+ if (this.hc != that.hc) return false;
+ if (!this.nodeId.equals(that.nodeId)) return false;
+ return this.propertyName.equals(that.propertyName);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return this.nodeId.toString() + '@' + this.propertyName.toString();
+ }
+
+}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SelfClosingInputStream.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SelfClosingInputStream.java 2009-04-30
04:32:26 UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SelfClosingInputStream.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -40,7 +40,7 @@
* </p>
*/
@NotThreadSafe
-public class SelfClosingInputStream extends InputStream {
+class SelfClosingInputStream extends InputStream {
private final Binary binary;
private final InputStream stream;
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-04-30 04:32:26
UTC (rev 866)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-04-30 15:31:52
UTC (rev 867)
@@ -121,7 +121,7 @@
* </p>
*/
@ThreadSafe
-public class SessionCache {
+class SessionCache {
/**
* Hidden flag that controls whether properties that appear on DNA nodes but not
allowed by the node type or mixins should be
Modified: trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties
===================================================================
--- trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties 2009-04-30
04:32:26 UTC (rev 866)
+++ trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties 2009-04-30
15:31:52 UTC (rev 867)
@@ -32,7 +32,8 @@
pathNotFoundRelativeTo = No item exists at path {0} relative to {1} in workspace
"{2}"
permissionDenied = Permission denied to perform actions "{1}" on path {0}.
repositoryMustBeConfigured = DNA repositories must be configured with either a repository
source factory or a repository source.
-sourceInUse = All sessions must end before a new repository source can be set.
+sourceInUse = All sessions must end before a new repository source can be set
+repositoryDoesNotExist = There is no repository named "{0}"
noNamespaceWithPrefix = There is no namespace with prefix "{0}"
noNamespaceWithUri = There is no namespace with URI "{0}"
Added: trunk/dna-repository/src/main/java/org/jboss/dna/repository/Configurator.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/Configurator.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/Configurator.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -0,0 +1,1051 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ * This software 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 java.util.ArrayList;
+import java.util.List;
+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.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.property.PathFactory;
+import org.jboss.dna.graph.property.ValueFormatException;
+import org.jboss.dna.graph.property.basic.RootPath;
+import org.jboss.dna.repository.sequencer.Sequencer;
+
+/**
+ * @param <BuilderType>
+ */
+public abstract class Configurator<BuilderType> {
+
+ /**
+ * Interface used to configure a sequencer.
+ *
+ * @param <ReturnType> the type of interface to return after the
sequencer's configuration is completed
+ */
+ public interface SequencerConfigurator<ReturnType> {
+
+ /**
+ * 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 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<ReturnType>>
addSequencer( final String id );
+ }
+
+ /**
+ * Interface used to initialize the configurator to use a specific repository
containing configuration information.
+ *
+ * @param <ReturnType> the configurator type returned after the configuration
repository is defined
+ */
+ public interface Initializer<ReturnType> {
+ /**
+ * Specify that this configuration should use a particular {@link
RepositorySource} for its configuration repository. By
+ * default each configuration uses an internal transient repository for its
configuration, but using this method will make
+ * the configuration use a different repository (that is perhaps shared with
other processes).
+ *
+ * @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,
ConfigRepositoryDetails<ReturnType>> withConfigurationRepository();
+ }
+
+ /**
+ * Interface used to configure a repository source.
+ *
+ * @param <ReturnType> the type of interface to return after the repository
source's configuration is completed
+ */
+ public interface RepositoryConfigurator<ReturnType> {
+ /**
+ * 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 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<ReturnType>>
addRepository( final String id );
+
+ /**
+ * 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 source the {@link RepositorySource} instance that should be used
+ * @return this configuration object, for method-chaining purposes
+ * @throws IllegalArgumentException if the repository source reference is null
+ * @see #addRepository(String)
+ */
+ public ReturnType addRepository( RepositorySource source );
+ }
+
+ /**
+ * Interface used to configure a MIME type detector.
+ *
+ * @param <ReturnType> the type of interface to return after the detector's
configuration is completed
+ */
+ public interface MimeDetectorConfigurator<ReturnType> {
+ /**
+ * 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 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<ReturnType>> addMimeTypeDetector( final String id );
+ }
+
+ /**
+ * Interface used to build the configured component.
+ *
+ * @param <ReturnType> the type of component that this configuration builds
+ */
+ public interface Builder<ReturnType> {
+ /**
+ * 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 ReturnType build() throws DnaConfigurationException;
+ }
+
+ /**
+ * Interface used to configure a {@link RepositorySource repository}.
+ *
+ * @param <ReturnType>
+ */
+ public interface RepositoryDetails<ReturnType>
+ extends SetName<RepositoryDetails<ReturnType>>,
SetDescription<RepositoryDetails<ReturnType>>,
+ SetProperties<RepositoryDetails<ReturnType>>, And<ReturnType>
{
+ }
+
+ /**
+ * Interface used to define the configuration repository.
+ *
+ * @param <ReturnType>
+ */
+ public interface ConfigRepositoryDetails<ReturnType>
+ extends SetDescription<ConfigRepositoryDetails<ReturnType>>,
SetProperties<ConfigRepositoryDetails<ReturnType>>,
+ And<ReturnType> {
+ /**
+ * Specify the path under which the configuration content is to be found. This
path is assumed to be "/" by default.
+ *
+ * @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 ConfigRepositoryDetails<ReturnType> under( String path );
+ }
+
+ /**
+ * Interface used to configure a {@link Sequencer sequencer}.
+ *
+ * @param <ReturnType>
+ */
+ public interface SequencerDetails<ReturnType>
+ extends SetName<SequencerDetails<ReturnType>>,
SetDescription<SequencerDetails<ReturnType>>, And<ReturnType> {
+
+ /**
+ * Specify the input {@link PathExpression path expression} represented as a
string, which determines when this sequencer
+ * will be executed.
+ *
+ * @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
+ */
+ PathExpressionOutput<ReturnType> sequencingFrom( String inputPathExpression
);
+
+ /**
+ * Specify the input {@link PathExpression path expression}, which determines
when this sequencer will be executed.
+ *
+ * @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 continue specifying the configuration of the
sequencer
+ */
+ SequencerDetails<ReturnType> sequencingFrom( PathExpression
inputPathExpression );
+ }
+
+ /**
+ * Interface used to specify the output path expression for a
+ * {@link Configurator.SequencerDetails#sequencingFrom(PathExpression) sequencer
configuration}.
+ *
+ * @param <ReturnType>
+ */
+ public interface PathExpressionOutput<ReturnType> {
+ /**
+ * Specify the output {@link PathExpression path expression}, which determines
where this sequencer's output will be
+ * placed.
+ *
+ * @param outputExpression the path expression for the location(s) where output
generated by the sequencer is to be placed
+ * @return the interface used to continue specifying the configuration of the
sequencer
+ */
+ SequencerDetails<ReturnType> andOutputtingTo( String outputExpression );
+ }
+
+ /**
+ * Interface used to configure a {@link MimeTypeDetector MIME type detector}.
+ *
+ * @param <ReturnType>
+ */
+ public interface MimeTypeDetectorDetails<ReturnType>
+ extends SetName<MimeTypeDetectorDetails<ReturnType>>,
SetDescription<MimeTypeDetectorDetails<ReturnType>>,
+ SetProperties<MimeTypeDetectorDetails<ReturnType>>,
And<ReturnType> {
+ }
+
+ /**
+ * Interface for configuring the JavaBean-style properties of an object.
+ *
+ * @param <ReturnType> the interface returned after the property has been set.
+ * @author Randall Hauch
+ */
+ public interface SetProperties<ReturnType> {
+ /**
+ * Specify the name of the JavaBean-style property that is to be set. The value
may be set using the interface returned by
+ * this method.
+ *
+ * @param beanPropertyName the name of the JavaBean-style property (e.g.,
"retryLimit")
+ * @return the interface used to set the value for the property; never null
+ */
+ PropertySetter<ReturnType> with( String beanPropertyName );
+ }
+
+ /**
+ * The interface used to set the value for a JavaBean-style property.
+ *
+ * @param <ReturnType> the interface returned from these methods
+ * @author Randall Hauch
+ * @see Configurator.SetProperties#with(String)
+ */
+ public interface PropertySetter<ReturnType> {
+ /**
+ * Set the property value to an integer.
+ *
+ * @param value the new value for the property
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType setTo( int value );
+
+ /**
+ * Set the property value to a long number.
+ *
+ * @param value the new value for the property
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType setTo( long value );
+
+ /**
+ * Set the property value to a short.
+ *
+ * @param value the new value for the property
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType setTo( short value );
+
+ /**
+ * Set the property value to a boolean.
+ *
+ * @param value the new value for the property
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType setTo( boolean value );
+
+ /**
+ * Set the property value to a float.
+ *
+ * @param value the new value for the property
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType setTo( float value );
+
+ /**
+ * Set the property value to a double.
+ *
+ * @param value the new value for the property
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType setTo( double value );
+
+ /**
+ * Set the property value to a string.
+ *
+ * @param value the new value for the property
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType setTo( String value );
+
+ /**
+ * Set the property value to an object.
+ *
+ * @param value the new value for the property
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType setTo( Object value );
+ }
+
+ /**
+ * The interface used to configure the class used for a component.
+ *
+ * @param <ComponentClassType> the class or interface that the component is to
implement
+ * @param <ReturnType> the interface returned from these methods
+ */
+ public interface ChooseClass<ComponentClassType, ReturnType> {
+
+ /**
+ * Specify the name of the class that should be instantiated for the instance.
The classpath information will need to be
+ * defined using the returned interface.
+ *
+ * @param classname the name of the class that should be instantiated
+ * @return the interface used to define the classpath information; never null
+ * @throws IllegalArgumentException if the class name is null, empty, blank, or
not a valid class name
+ */
+ LoadedFrom<ReturnType> usingClass( String classname );
+
+ /**
+ * Specify the class that should be instantiated for the instance. Because the
class is already available to this class
+ * loader, there is no need to specify the classloader information.
+ *
+ * @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 );
+ }
+
+ /**
+ * The interface used to set a description on a component.
+ *
+ * @param <ReturnType> the interface returned from these methods
+ */
+ public interface SetDescription<ReturnType> {
+ /**
+ * Specify the description of this component.
+ *
+ * @param description the description; may be null or empty
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType describedAs( String description );
+ }
+
+ /**
+ * 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
+ */
+ public interface LoadedFrom<ReturnType> {
+ /**
+ * Specify the names of the classloaders that form the classpath for the
component, from which the component's class (and
+ * its dependencies) can be loaded. The names correspond to the names supplied to
the
+ * {@link ExecutionContext#getClassLoader(String...)} methods.
+ *
+ * @param classPathNames the names for the classloaders, as passed to the {@link
ClassLoaderFactory} implementation (e.g.,
+ * the {@link ExecutionContext}).
+ * @return the next component to continue configuration; never null
+ * @see #loadedFromClasspath()
+ * @see ExecutionContext#getClassLoader(String...)
+ */
+ ReturnType loadedFrom( String... classPathNames );
+
+ /**
+ * Specify that the component (and its dependencies) will be found on the current
(or
+ * {@link Thread#getContextClassLoader() current context}) classloader.
+ *
+ * @return the next component to continue configuration; never null
+ * @see #loadedFrom(String...)
+ * @see ExecutionContext#getClassLoader(String...)
+ */
+ ReturnType loadedFromClasspath();
+ }
+
+ /**
+ * Continue with another aspect of configuration.
+ *
+ * @param <ReturnType>
+ */
+ public interface And<ReturnType> {
+
+ /**
+ * Return a reference to the next configuration interface for additional
operations.
+ *
+ * @return a reference to the next configuration interface
+ */
+ ReturnType and();
+ }
+
+ protected final BuilderType builder;
+ protected final ExecutionContext context;
+ protected ConfigurationRepository configurationSource;
+ private Graph graph;
+ private Graph.Batch batch;
+
+ /**
+ * 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
+ * @param builder the builder
+ * @throws IllegalArgumentException if the supplied context reference is null
+ */
+ protected Configurator( ExecutionContext context,
+ BuilderType builder ) {
+ CheckArg.isNotNull(context, "context");
+ CheckArg.isNotNull(builder, "builder");
+ this.context = context;
+ this.builder = builder;
+
+ // 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 ConfigurationRepository createDefaultConfigurationSource() {
+ InMemoryRepositorySource defaultSource = new InMemoryRepositorySource();
+ defaultSource.setName("Configuration");
+ ConfigurationRepository result = new ConfigurationRepository(defaultSource,
"Configuration Repository", null);
+ return result;
+ }
+
+ /**
+ * Get the execution context used by this configurator.
+ *
+ * @return the execution context; never null
+ */
+ public final ExecutionContext getExecutionContext() {
+ return this.context;
+ }
+
+ protected final PathFactory pathFactory() {
+ return getExecutionContext().getValueFactories().getPathFactory();
+ }
+
+ /**
+ * Get the graph containing the configuration information.
+ *
+ * @return the configuration repository graph; never null
+ * @see #graph()
+ */
+ protected final Graph graph() {
+ if (this.graph == null) {
+ this.graph = Graph.create(configurationSource.getRepositorySource(),
context);
+ }
+ return this.graph;
+ }
+
+ /**
+ * Get the graph batch that can be used to change the configuration, where the
changes are enqueued until {@link #save()
+ * saved}.
+ *
+ * @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.batch;
+ }
+
+ /**
+ * Save any changes that have been made so far to the configuration. This method does
nothing if no changes have been made.
+ *
+ * @return this configuration object for method chaining purposes; never null
+ */
+ public BuilderType save() {
+ if (this.batch != null) {
+ this.batch.execute();
+ this.batch = this.graph.batch();
+ }
+ return this.builder;
+ }
+
+ protected abstract Name nameFor( String name );
+
+ protected Path createOrReplaceNode( Path parentPath,
+ String id ) {
+ Path path = pathFactory().create(parentPath, id);
+ configuration().create(path).with(DnaLexicon.READABLE_NAME, id).and();
+ return path;
+ }
+
+ protected void recordBeanPropertiesInGraph( Path path,
+ Object javaBean ) {
+ Reflection reflector = new Reflection(javaBean.getClass());
+ for (String propertyName : reflector.findGetterPropertyNames()) {
+ Object value;
+ try {
+ value = reflector.invokeGetterMethodOnTarget(propertyName, javaBean);
+ if (value == null) continue;
+ propertyName = Inflector.getInstance().lowerCamelCase(propertyName);
+ configuration().set(nameFor(propertyName)).to(value).on(path);
+ } catch (ValueFormatException err) {
+ throw err;
+ } catch (Throwable err) {
+ // Unable to call getter and set property
+ }
+ }
+ }
+
+ protected class ConfigurationRepositoryClassChooser<ReturnType>
+ implements ChooseClass<RepositorySource,
ConfigRepositoryDetails<ReturnType>> {
+
+ private final ReturnType returnObject;
+
+ protected ConfigurationRepositoryClassChooser( ReturnType returnObject ) {
+ assert returnObject != null;
+ this.returnObject = returnObject;
+ }
+
+ public LoadedFrom<ConfigRepositoryDetails<ReturnType>> usingClass(
final String className ) {
+ return new LoadedFrom<ConfigRepositoryDetails<ReturnType>>() {
+ @SuppressWarnings( "unchecked" )
+ public ConfigRepositoryDetails loadedFrom( String... classpath ) {
+ ClassLoader classLoader =
getExecutionContext().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<ReturnType> usingClass( Class<? extends
RepositorySource> repositorySource ) {
+ try {
+ Configurator.this.configurationSource = new
ConfigurationRepository(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<ReturnType>(returnObject);
+ }
+ }
+
+ protected class ConfigurationSourceDetails<ReturnType> implements
ConfigRepositoryDetails<ReturnType> {
+ private final ReturnType returnObject;
+
+ protected ConfigurationSourceDetails( ReturnType returnObject ) {
+ assert returnObject != null;
+ this.returnObject = returnObject;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SetDescription#describedAs(java.lang.String)
+ */
+ public ConfigRepositoryDetails<ReturnType> describedAs( String description
) {
+ Configurator.this.configurationSource =
Configurator.this.configurationSource.with(description);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SetProperties#with(java.lang.String)
+ */
+ public PropertySetter<ConfigRepositoryDetails<ReturnType>> with(
String propertyName ) {
+ return new
BeanPropertySetter<ConfigRepositoryDetails<ReturnType>>(
+
Configurator.this.configurationSource.getRepositorySource(),
+
propertyName, this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.ConfigRepositoryDetails#under(java.lang.String)
+ */
+ public ConfigRepositoryDetails<ReturnType> under( String path ) {
+ CheckArg.isNotNull(path, "path");
+ Path newPath =
getExecutionContext().getValueFactories().getPathFactory().create(path);
+ Configurator.this.configurationSource =
Configurator.this.configurationSource.with(newPath);
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator.And#and()
+ */
+ public ReturnType and() {
+ return returnObject;
+ }
+ }
+
+ /**
+ * Reusable implementation of {@link Configurator.ChooseClass} that can be used to
obtain the name of a class and how its
+ * class loader is defined.
+ *
+ * @param <ComponentClass> the type of the component that is being chosen
+ * @param <ReturnType> the interface that should be returned when the class
name and classpath have been chosen.
+ */
+ protected class ClassChooser<ComponentClass, ReturnType> implements
Configurator.ChooseClass<ComponentClass, ReturnType> {
+ protected final Path pathOfComponentNode;
+ protected final ReturnType returnObject;
+
+ protected ClassChooser( Path pathOfComponentNode,
+ ReturnType returnObject ) {
+ assert pathOfComponentNode != null;
+ assert returnObject != null;
+ this.pathOfComponentNode = pathOfComponentNode;
+ this.returnObject = returnObject;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see Configurator.ChooseClass#usingClass(java.lang.String)
+ */
+ public Configurator.LoadedFrom<ReturnType> usingClass( final String
classname ) {
+ CheckArg.isNotEmpty(classname, "classname");
+
configuration().set(DnaLexicon.CLASSNAME).to(classname).on(pathOfComponentNode);
+ return new Configurator.LoadedFrom<ReturnType>() {
+ public ReturnType loadedFromClasspath() {
+ return returnObject;
+ }
+
+ public ReturnType loadedFrom( String... 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;
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see Configurator.ChooseClass#usingClass(java.lang.Class)
+ */
+ public ReturnType usingClass( Class<? extends ComponentClass> clazz ) {
+ CheckArg.isNotNull(clazz, "clazz");
+ return usingClass(clazz.getName()).loadedFromClasspath();
+ }
+ }
+
+ /**
+ * Reusable implementation of {@link Configurator.PropertySetter} that sets the
JavaBean-style property using reflection.
+ *
+ * @param <ReturnType>
+ */
+ protected class BeanPropertySetter<ReturnType> implements
Configurator.PropertySetter<ReturnType> {
+ private final Object javaBean;
+ private final String beanPropertyName;
+ private final ReturnType returnObject;
+
+ protected BeanPropertySetter( Object javaBean,
+ String beanPropertyName,
+ ReturnType returnObject ) {
+ assert javaBean != null;
+ assert beanPropertyName != null;
+ assert returnObject != null;
+ this.javaBean = javaBean;
+ this.beanPropertyName = beanPropertyName;
+ this.returnObject = returnObject;
+ }
+
+ public ReturnType setTo( boolean value ) {
+ return setTo((Object)value);
+ }
+
+ public ReturnType setTo( int value ) {
+ return setTo((Object)value);
+ }
+
+ public ReturnType setTo( long value ) {
+ return setTo((Object)value);
+ }
+
+ public ReturnType setTo( short value ) {
+ return setTo((Object)value);
+ }
+
+ public ReturnType setTo( float value ) {
+ return setTo((Object)value);
+ }
+
+ public ReturnType setTo( double value ) {
+ return setTo((Object)value);
+ }
+
+ public ReturnType setTo( String value ) {
+ return setTo((Object)value);
+ }
+
+ public ReturnType setTo( Object value ) {
+ // Set the JavaBean-style property on the RepositorySource instance ...
+ Reflection reflection = new Reflection(javaBean.getClass());
+ try {
+ reflection.invokeSetterMethodOnTarget(beanPropertyName, javaBean,
value);
+ } catch (Throwable err) {
+ I18n msg = RepositoryI18n.errorSettingJavaBeanPropertyOnInstanceOfClass;
+ throw new DnaConfigurationException(msg.text(beanPropertyName,
javaBean.getClass(), err.getMessage()), err);
+ }
+ return returnObject;
+ }
+ }
+
+ /**
+ * Reusable implementation of {@link Configurator.PropertySetter} that sets the
property on the specified node in the
+ * configuration graph.
+ *
+ * @param <ReturnType>
+ */
+ protected class GraphPropertySetter<ReturnType> implements
Configurator.PropertySetter<ReturnType> {
+ private final Path path;
+ private final String beanPropertyName;
+ private final ReturnType returnObject;
+
+ protected GraphPropertySetter( Path path,
+ String beanPropertyName,
+ ReturnType returnObject ) {
+ assert path != null;
+ assert beanPropertyName != null;
+ assert returnObject != null;
+ this.path = path;
+ this.beanPropertyName =
Inflector.getInstance().lowerCamelCase(beanPropertyName);
+ this.returnObject = returnObject;
+ }
+
+ public ReturnType setTo( boolean value ) {
+ configuration().set(nameFor(beanPropertyName)).to(value).on(path);
+ return returnObject;
+ }
+
+ public ReturnType setTo( int value ) {
+ configuration().set(nameFor(beanPropertyName)).to(value).on(path);
+ return returnObject;
+ }
+
+ public ReturnType setTo( long value ) {
+ configuration().set(nameFor(beanPropertyName)).to(value).on(path);
+ return returnObject;
+ }
+
+ public ReturnType setTo( short value ) {
+ configuration().set(nameFor(beanPropertyName)).to(value).on(path);
+ return returnObject;
+ }
+
+ public ReturnType setTo( float value ) {
+ configuration().set(nameFor(beanPropertyName)).to(value).on(path);
+ return returnObject;
+ }
+
+ public ReturnType setTo( double value ) {
+ configuration().set(nameFor(beanPropertyName)).to(value).on(path);
+ return returnObject;
+ }
+
+ public ReturnType setTo( String value ) {
+ configuration().set(nameFor(beanPropertyName)).to(value).on(path);
+ return returnObject;
+ }
+
+ public ReturnType setTo( Object value ) {
+ configuration().set(nameFor(beanPropertyName)).to(value).on(path);
+ return returnObject;
+ }
+ }
+
+ protected class GraphRepositoryDetails<ReturnType> implements
RepositoryDetails<ReturnType> {
+ private final Path path;
+ private final ReturnType returnObject;
+
+ protected GraphRepositoryDetails( Path path,
+ ReturnType returnObject ) {
+ assert path != null;
+ assert returnObject != null;
+ this.path = path;
+ this.returnObject = returnObject;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator.SetName#named(java.lang.String)
+ */
+ public RepositoryDetails<ReturnType> named( String name ) {
+ configuration().set(DnaLexicon.READABLE_NAME).to(name).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SetDescription#describedAs(java.lang.String)
+ */
+ public RepositoryDetails<ReturnType> describedAs( String description ) {
+ configuration().set(DnaLexicon.DESCRIPTION).to(description).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SetProperties#with(java.lang.String)
+ */
+ public PropertySetter<RepositoryDetails<ReturnType>> with( String
propertyName ) {
+ return new
GraphPropertySetter<RepositoryDetails<ReturnType>>(path, propertyName, this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator.And#and()
+ */
+ public ReturnType and() {
+ return returnObject;
+ }
+ }
+
+ protected class GraphSequencerDetails<ReturnType> implements
SequencerDetails<ReturnType> {
+ private final Path path;
+ private final List<String> compiledExpressions = new
ArrayList<String>();
+ private final ReturnType returnObject;
+
+ protected GraphSequencerDetails( Path path,
+ ReturnType returnObject ) {
+ assert path != null;
+ assert returnObject != null;
+ this.path = path;
+ this.returnObject = returnObject;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SequencerDetails#sequencingFrom(java.lang.String)
+ */
+ public PathExpressionOutput<ReturnType> sequencingFrom( final String from )
{
+ CheckArg.isNotEmpty(from, "from");
+ return new PathExpressionOutput<ReturnType>() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.PathExpressionOutput#andOutputtingTo(java.lang.String)
+ */
+ public SequencerDetails<ReturnType> andOutputtingTo( String into )
{
+ CheckArg.isNotEmpty(into, "into");
+ return sequencingFrom(PathExpression.compile(from + " =>
" + into));
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator.SetName#named(java.lang.String)
+ */
+ public SequencerDetails<ReturnType> named( String name ) {
+ configuration().set(DnaLexicon.READABLE_NAME).to(name).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SequencerDetails#sequencingFrom(org.jboss.dna.graph.property.PathExpression)
+ */
+ public SequencerDetails<ReturnType> sequencingFrom( PathExpression
expression ) {
+ CheckArg.isNotNull(expression, "expression");
+ String compiledExpression = expression.getExpression();
+ if (!compiledExpressions.contains(compiledExpression))
compiledExpressions.add(compiledExpression);
+
configuration().set(DnaLexicon.PATH_EXPRESSIONS).on(path).to(compiledExpressions);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SetDescription#describedAs(java.lang.String)
+ */
+ public SequencerDetails<ReturnType> describedAs( String description ) {
+ configuration().set(DnaLexicon.DESCRIPTION).to(description).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator.And#and()
+ */
+ public ReturnType and() {
+ return returnObject;
+ }
+ }
+
+ protected class GraphMimeTypeDetectorDetails<ReturnType> implements
MimeTypeDetectorDetails<ReturnType> {
+ private final Path path;
+ private final ReturnType returnObject;
+
+ protected GraphMimeTypeDetectorDetails( Path path,
+ ReturnType returnObject ) {
+ assert path != null;
+ assert returnObject != null;
+ this.path = path;
+ this.returnObject = returnObject;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator.SetName#named(java.lang.String)
+ */
+ public MimeTypeDetectorDetails<ReturnType> named( String name ) {
+ configuration().set(DnaLexicon.READABLE_NAME).to(name).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SetProperties#with(java.lang.String)
+ */
+ public PropertySetter<MimeTypeDetectorDetails<ReturnType>> with(
String propertyName ) {
+ return new
GraphPropertySetter<MimeTypeDetectorDetails<ReturnType>>(path, propertyName,
this);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SetDescription#describedAs(java.lang.String)
+ */
+ public MimeTypeDetectorDetails<ReturnType> describedAs( String description
) {
+ configuration().set(DnaLexicon.DESCRIPTION).to(description).on(path);
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator.And#and()
+ */
+ public ReturnType and() {
+ return returnObject;
+ }
+ }
+
+ @Immutable
+ public static class ConfigurationRepository {
+ private final RepositorySource source;
+ private final String description;
+ private final Path path;
+
+ protected ConfigurationRepository( RepositorySource source ) {
+ this(source, null, null);
+ }
+
+ protected ConfigurationRepository( RepositorySource source,
+ String description,
+ Path path ) {
+ this.source = source;
+ this.description = description != null ? description : "";
+ this.path = path != null ? path : RootPath.INSTANCE;
+ }
+
+ /**
+ * @return source
+ */
+ public RepositorySource getRepositorySource() {
+ return source;
+ }
+
+ /**
+ * @return description
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * @return path
+ */
+ public Path getPath() {
+ return path;
+ }
+
+ public ConfigurationRepository with( String description ) {
+ return new ConfigurationRepository(source, description, path);
+ }
+
+ public ConfigurationRepository with( Path path ) {
+ return new ConfigurationRepository(source, description, path);
+ }
+ }
+}
Property changes on:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/Configurator.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Deleted:
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-30
04:32:26 UTC (rev 866)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -1,1074 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * 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.
- *
- * This software 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 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.property.PathFactory;
-import org.jboss.dna.graph.property.ValueFormatException;
-import org.jboss.dna.graph.property.basic.RootPath;
-import org.jboss.dna.repository.sequencer.Sequencer;
-
-/**
- */
-@Immutable
-public class DnaConfiguration {
-
- 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);
- }
-
- @Immutable
- protected class ConfigurationRepository {
- private final RepositorySource source;
- private final String description;
- private final Path path;
-
- protected ConfigurationRepository( RepositorySource source ) {
- this(source, null, null);
- }
-
- protected ConfigurationRepository( RepositorySource source,
- String description,
- Path path ) {
- this.source = source;
- this.description = description != null ? description : "";
- this.path = path != null ? path : RootPath.INSTANCE;
- }
-
- /**
- * @return source
- */
- public RepositorySource getRepositorySource() {
- return source;
- }
-
- /**
- * @return description
- */
- public String getDescription() {
- return description;
- }
-
- /**
- * @return path
- */
- public Path getPath() {
- return path;
- }
-
- public ConfigurationRepository with( String description ) {
- return new ConfigurationRepository(source, description, path);
- }
-
- public ConfigurationRepository with( Path path ) {
- return new ConfigurationRepository(source, description, path);
- }
- }
-
- private final ExecutionContext context;
- protected ConfigurationRepository configurationSource;
- private Path sourcesPath;
- private Path sequencersPath;
- private Path detectorsPath;
- private Graph graph;
- private Graph.Batch batch;
-
- /**
- * Create a new configuration for DNA.
- */
- public DnaConfiguration() {
- this(new ExecutionContext());
- }
-
- /**
- * 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;
-
- // 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 ConfigurationRepository createDefaultConfigurationSource() {
- InMemoryRepositorySource defaultSource = new InMemoryRepositorySource();
- defaultSource.setName("Configuration");
- ConfigurationRepository result = new ConfigurationRepository(defaultSource,
"Configuration Repository", null);
- return result;
- }
-
- protected final ExecutionContext context() {
- return this.context;
- }
-
- protected final PathFactory pathFactory() {
- return context().getValueFactories().getPathFactory();
- }
-
- /**
- * 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.getRepositorySource(),
context);
- }
- return this.graph;
- }
-
- /**
- * 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.batch;
- }
-
- /**
- * Save any changes that have been made so far to the configuration. This method does
nothing if no changes have been made.
- *
- * @return this configuration object for method chaining purposes; never null
- */
- public DnaConfiguration save() {
- if (this.batch != null) {
- this.batch.execute();
- this.batch = this.graph.batch();
- }
- return this;
- }
-
- /**
- * Specify that this configuration should use a particular {@link RepositorySource}
for its configuration repository. By
- * default each configuration uses an internal transient repository for its
configuration, but using this method will make the
- * configuration use a different repository (that is perhaps shared with other
processes).
- *
- * @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, ConfigRepositoryDetails>
withConfigurationRepository() {
- // 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 {
- DnaConfiguration.this.configurationSource = new
ConfigurationRepository(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 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 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));
- }
-
- /**
- * 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 source the {@link RepositorySource} instance that should be used
- * @return this configuration object, for method-chaining purposes
- * @throws IllegalArgumentException if the repository source reference is null
- * @see #addRepository(String)
- */
- public DnaConfiguration addRepository( RepositorySource 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 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 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 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 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 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() throws DnaConfigurationException {
- save();
- return new DnaEngine(this);
- }
-
- protected Path sourcesPath() {
- // Make sure the "dna:sources" node is there
- if (sourcesPath == null) {
- Path path = pathFactory().create(this.configurationSource.getPath(),
DnaLexicon.SOURCES);
- Node node = graph().createIfMissing(path).andReturn();
- this.sourcesPath = node.getLocation().getPath();
- }
- return this.sourcesPath;
- }
-
- protected Path sequencersPath() {
- // Make sure the "dna:sequencers" node is there
- if (sequencersPath == null) {
- Path path = pathFactory().create(this.configurationSource.getPath(),
DnaLexicon.SEQUENCERS);
- Node node = graph().createIfMissing(path).andReturn();
- this.sequencersPath = node.getLocation().getPath();
- }
- return this.sequencersPath;
- }
-
- protected Path detectorsPath() {
- // Make sure the "dna:mimeTypeDetectors" node is there
- if (detectorsPath == null) {
- Path path = pathFactory().create(this.configurationSource.getPath(),
DnaLexicon.MIME_TYPE_DETECTORS);
- Node node = graph().createIfMissing(path).andReturn();
- this.detectorsPath = node.getLocation().getPath();
- }
- return this.detectorsPath;
- }
-
- /**
- * Interface used to configure a {@link RepositorySource repository}.
- */
- public interface RepositoryDetails
- extends SetName<RepositoryDetails>,
SetDescription<RepositoryDetails>, SetProperties<RepositoryDetails>,
- ConfigurationBuilder {
- }
-
- public interface ConfigRepositoryDetails
- extends SetDescription<ConfigRepositoryDetails>,
SetProperties<ConfigRepositoryDetails>, ConfigurationBuilder {
- /**
- * Specify the path under which the configuration content is to be found. This
path is assumed to be "/" by default.
- *
- * @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 ConfigRepositoryDetails under( String path );
- }
-
- /**
- * Interface used to configure a {@link Sequencer sequencer}.
- */
- 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
- * will be executed.
- *
- * @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
- */
- PathExpressionOutput sequencingFrom( String inputPathExpression );
-
- /**
- * Specify the input {@link PathExpression path expression}, which determines
when this sequencer will be executed.
- *
- * @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 continue specifying the configuration of the
sequencer
- */
- SequencerDetails sequencingFrom( PathExpression inputPathExpression );
- }
-
- /**
- * Interface used to specify the output path expression for a {@link
SequencerDetails#sequencingFrom(PathExpression) sequencer
- * configuration}.
- */
- public interface PathExpressionOutput {
- /**
- * Specify the output {@link PathExpression path expression}, which determines
where this sequencer's output will be
- * placed.
- *
- * @param outputExpression the path expression for the location(s) where output
generated by the sequencer is to be placed
- * @return the interface used to continue specifying the configuration of the
sequencer
- */
- SequencerDetails andOutputtingTo( String outputExpression );
- }
-
- /**
- * Interface used to configure a {@link MimeTypeDetector MIME type detector}.
- */
- public interface MimeTypeDetectorDetails
- extends SetName<MimeTypeDetectorDetails>,
SetDescription<MimeTypeDetectorDetails>,
- SetProperties<MimeTypeDetectorDetails>, ConfigurationBuilder {
- }
-
- /**
- * Interface for configuring the JavaBean-style properties of an object.
- *
- * @param <ReturnType> the interface returned after the property has been set.
- * @author Randall Hauch
- */
- public interface SetProperties<ReturnType> {
- /**
- * Specify the name of the JavaBean-style property that is to be set. The value
may be set using the interface returned by
- * this method.
- *
- * @param beanPropertyName the name of the JavaBean-style property (e.g.,
"retryLimit")
- * @return the interface used to set the value for the property; never null
- */
- PropertySetter<ReturnType> with( String beanPropertyName );
- }
-
- /**
- * The interface used to set the value for a JavaBean-style property.
- *
- * @param <ReturnType> the interface returned from these methods
- * @author Randall Hauch
- * @see SetProperties#with(String)
- */
- public interface PropertySetter<ReturnType> {
- /**
- * Set the property value to an integer.
- *
- * @param value the new value for the property
- * @return the next component to continue configuration; never null
- */
- ReturnType setTo( int value );
-
- /**
- * Set the property value to a long number.
- *
- * @param value the new value for the property
- * @return the next component to continue configuration; never null
- */
- ReturnType setTo( long value );
-
- /**
- * Set the property value to a short.
- *
- * @param value the new value for the property
- * @return the next component to continue configuration; never null
- */
- ReturnType setTo( short value );
-
- /**
- * Set the property value to a boolean.
- *
- * @param value the new value for the property
- * @return the next component to continue configuration; never null
- */
- ReturnType setTo( boolean value );
-
- /**
- * Set the property value to a float.
- *
- * @param value the new value for the property
- * @return the next component to continue configuration; never null
- */
- ReturnType setTo( float value );
-
- /**
- * Set the property value to a double.
- *
- * @param value the new value for the property
- * @return the next component to continue configuration; never null
- */
- ReturnType setTo( double value );
-
- /**
- * Set the property value to a string.
- *
- * @param value the new value for the property
- * @return the next component to continue configuration; never null
- */
- ReturnType setTo( String value );
-
- /**
- * Set the property value to an object.
- *
- * @param value the new value for the property
- * @return the next component to continue configuration; never null
- */
- ReturnType setTo( Object value );
- }
-
- /**
- * The interface used to configure the class used for a component.
- *
- * @param <ComponentClassType> the class or interface that the component is to
implement
- * @param <ReturnType> the interface returned from these methods
- */
- public interface ChooseClass<ComponentClassType, ReturnType> {
-
- /**
- * Specify the name of the class that should be instantiated for the instance.
The classpath information will need to be
- * defined using the returned interface.
- *
- * @param classname the name of the class that should be instantiated
- * @return the interface used to define the classpath information; never null
- * @throws IllegalArgumentException if the class name is null, empty, blank, or
not a valid class name
- */
- LoadedFrom<ReturnType> usingClass( String classname );
-
- /**
- * Specify the class that should be instantiated for the instance. Because the
class is already available to this class
- * loader, there is no need to specify the classloader information.
- *
- * @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 );
- }
-
- /**
- * The interface used to set a description on a component.
- *
- * @param <ReturnType> the interface returned from these methods
- */
- public interface SetDescription<ReturnType> {
- /**
- * Specify the description of this component.
- *
- * @param description the description; may be null or empty
- * @return the next component to continue configuration; never null
- */
- ReturnType describedAs( String description );
- }
-
- /**
- * 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
- */
- public interface LoadedFrom<ReturnType> {
- /**
- * Specify the names of the classloaders that form the classpath for the
component, from which the component's class (and
- * its dependencies) can be loaded. The names correspond to the names supplied to
the
- * {@link ExecutionContext#getClassLoader(String...)} methods.
- *
- * @param classPathNames the names for the classloaders, as passed to the {@link
ClassLoaderFactory} implementation (e.g.,
- * the {@link ExecutionContext}).
- * @return the next component to continue configuration; never null
- * @see #loadedFromClasspath()
- * @see ExecutionContext#getClassLoader(String...)
- */
- ReturnType loadedFrom( String... classPathNames );
-
- /**
- * Specify that the component (and its dependencies) will be found on the current
(or
- * {@link Thread#getContextClassLoader() current context}) classloader.
- *
- * @return the next component to continue configuration; never null
- * @see #loadedFrom(String...)
- * @see ExecutionContext#getClassLoader(String...)
- */
- ReturnType loadedFromClasspath();
- }
-
- /**
- * Interface for classes that can return a reference to their DNA configuration.
- */
- public interface ConfigurationBuilder {
-
- /**
- * Return a reference to the enclosing configuration so that it can be built or
further configured.
- *
- * @return a reference to the enclosing configuration
- */
- 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 =
DnaConfiguration.this.configurationSource.with(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.getRepositorySource(),
- propertyName, this);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.repository.DnaConfiguration.ConfigRepositoryDetails#under(java.lang.String)
- */
- public ConfigRepositoryDetails under( String path ) {
- CheckArg.isNotNull(path, "path");
- Path newPath = context().getValueFactories().getPathFactory().create(path);
- DnaConfiguration.this.configurationSource =
DnaConfiguration.this.configurationSource.with(newPath);
- 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;
- private final List<String> compiledExpressions = new
ArrayList<String>();
-
- 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");
- String compiledExpression = expression.getExpression();
- if (!compiledExpressions.contains(compiledExpression))
compiledExpressions.add(compiledExpression);
-
configuration().set(DnaLexicon.PATH_EXPRESSIONS).on(path).to(compiledExpressions);
- 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.
- *
- * @param <ComponentClass> the type of the component that is being chosen
- * @param <ReturnType> the interface that should be returned when the class
name and classpath have been chosen.
- * @author Randall Hauch
- */
- protected class ClassChooser<ComponentClass, ReturnType> implements
ChooseClass<ComponentClass, ReturnType> {
- protected final Path pathOfComponentNode;
- protected final ReturnType returnObject;
-
- protected ClassChooser( Path pathOfComponentNode,
- ReturnType returnObject ) {
- assert pathOfComponentNode != null;
- assert returnObject != null;
- this.pathOfComponentNode = pathOfComponentNode;
- this.returnObject = returnObject;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.repository.DnaConfiguration.ChooseClass#usingClass(java.lang.String)
- */
- 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 returnObject;
- }
-
- public ReturnType loadedFrom( String... 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;
- }
- };
- }
-
- /**
- * {@inheritDoc}
- *
- * @see
org.jboss.dna.repository.DnaConfiguration.ChooseClass#usingClass(java.lang.Class)
- */
- public ReturnType usingClass( Class<? extends ComponentClass> clazz ) {
- CheckArg.isNotNull(clazz, "clazz");
- return usingClass(clazz.getName()).loadedFromClasspath();
- }
- }
-
- /**
- * Reusable implementation of {@link PropertySetter} that sets the JavaBean-style
property using reflection.
- *
- * @param <ReturnType>
- * @author Randall Hauch
- */
- protected class BeanPropertySetter<ReturnType> implements
PropertySetter<ReturnType> {
- private final Object javaBean;
- private final String beanPropertyName;
- private final ReturnType returnObject;
-
- protected BeanPropertySetter( Object javaBean,
- String beanPropertyName,
- ReturnType returnObject ) {
- assert javaBean != null;
- assert beanPropertyName != null;
- assert returnObject != null;
- this.javaBean = javaBean;
- this.beanPropertyName = beanPropertyName;
- this.returnObject = returnObject;
- }
-
- public ReturnType setTo( boolean value ) {
- return setTo((Object)value);
- }
-
- public ReturnType setTo( int value ) {
- return setTo((Object)value);
- }
-
- public ReturnType setTo( long value ) {
- return setTo((Object)value);
- }
-
- public ReturnType setTo( short value ) {
- return setTo((Object)value);
- }
-
- public ReturnType setTo( float value ) {
- return setTo((Object)value);
- }
-
- public ReturnType setTo( double value ) {
- return setTo((Object)value);
- }
-
- public ReturnType setTo( String value ) {
- return setTo((Object)value);
- }
-
- public ReturnType setTo( Object value ) {
- // Set the JavaBean-style property on the RepositorySource instance ...
- Reflection reflection = new Reflection(javaBean.getClass());
- try {
- reflection.invokeSetterMethodOnTarget(beanPropertyName, javaBean,
value);
- } catch (Throwable err) {
- I18n msg = RepositoryI18n.errorSettingJavaBeanPropertyOnInstanceOfClass;
- throw new DnaConfigurationException(msg.text(beanPropertyName,
javaBean.getClass(), err.getMessage()), err);
- }
- return returnObject;
- }
- }
-
- /**
- * Reusable implementation of {@link PropertySetter} that sets the property on the
specified node in the configuration graph.
- *
- * @param <ReturnType>
- * @author Randall Hauch
- */
- protected class GraphPropertySetter<ReturnType> implements
PropertySetter<ReturnType> {
- private final Path path;
- private final String beanPropertyName;
- private final ReturnType returnObject;
-
- protected GraphPropertySetter( Path path,
- String beanPropertyName,
- ReturnType returnObject ) {
- assert path != null;
- assert beanPropertyName != null;
- assert returnObject != null;
- this.path = path;
- this.beanPropertyName =
Inflector.getInstance().lowerCamelCase(beanPropertyName);
- this.returnObject = returnObject;
- }
-
- public ReturnType setTo( boolean 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 ) {
- 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 ) {
- 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 ) {
- 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 ) {
- 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 ) {
- 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 ) {
- 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 ) {
- 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;
- }
- }
-}
Added: trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -0,0 +1,302 @@
+/*
+ * 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.
+ *
+ * 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 java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.jboss.dna.common.util.CheckArg;
+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.mimetype.MimeTypeDetector;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.repository.Configurator.ChooseClass;
+import org.jboss.dna.repository.Configurator.ConfigRepositoryDetails;
+import org.jboss.dna.repository.Configurator.ConfigurationRepository;
+import org.jboss.dna.repository.Configurator.MimeTypeDetectorDetails;
+import org.jboss.dna.repository.Configurator.RepositoryDetails;
+import org.jboss.dna.repository.Configurator.SequencerDetails;
+import org.jboss.dna.repository.sequencer.Sequencer;
+
+/**
+ *
+ */
+public class DnaConfiguration
+ implements Configurator.Initializer<DnaConfiguration>,
Configurator.SequencerConfigurator<DnaConfiguration>,
+ Configurator.RepositoryConfigurator<DnaConfiguration>,
Configurator.MimeDetectorConfigurator<DnaConfiguration>,
+ Configurator.Builder<DnaEngine> {
+
+ 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);
+ }
+
+ private final Builder<DnaConfiguration> builder;
+
+ /**
+ * Create a new configuration for DNA.
+ */
+ public DnaConfiguration() {
+ this(new ExecutionContext());
+ }
+
+ /**
+ * 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 ) {
+ this.builder = new Builder<DnaConfiguration>(context, this);
+ }
+
+ /**
+ * Get the execution context used by this configurator.
+ *
+ * @return the execution context; never null
+ */
+ public final ExecutionContext getExecutionContext() {
+ return builder.getExecutionContext();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.Initializer#withConfigurationRepository()
+ */
+ public ChooseClass<RepositorySource,
ConfigRepositoryDetails<DnaConfiguration>> withConfigurationRepository() {
+ return builder.withConfigurationRepository();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.RepositoryConfigurator#addRepository(java.lang.String)
+ */
+ public ChooseClass<RepositorySource, RepositoryDetails<DnaConfiguration>>
addRepository( String id ) {
+ return builder.addRepository(id);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.RepositoryConfigurator#addRepository(org.jboss.dna.graph.connector.RepositorySource)
+ */
+ public DnaConfiguration addRepository( RepositorySource source ) {
+ return builder.addRepository(source);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SequencerConfigurator#addSequencer(java.lang.String)
+ */
+ public ChooseClass<Sequencer, SequencerDetails<DnaConfiguration>>
addSequencer( String id ) {
+ return builder.addSequencer(id);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.MimeDetectorConfigurator#addMimeTypeDetector(java.lang.String)
+ */
+ public ChooseClass<MimeTypeDetector,
MimeTypeDetectorDetails<DnaConfiguration>> addMimeTypeDetector( String id ) {
+ return builder.addMimeTypeDetector(id);
+ }
+
+ /**
+ * Save any changes that have been made so far to the configuration. This method does
nothing if no changes have been made.
+ *
+ * @return this configuration object for method chaining purposes; never null
+ */
+ public DnaConfiguration save() {
+ return builder.save();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator.Builder#build()
+ */
+ public DnaEngine build() throws DnaConfigurationException {
+ save();
+ return new DnaEngine(builder.getExecutionContext(),
builder.configurationSource);
+ }
+
+ protected Graph graph() {
+ return builder.graph();
+ }
+
+ protected ConfigurationRepository configurationRepository() {
+ return builder.configurationSource;
+ }
+
+ public static class Builder<ReturnType> extends Configurator<ReturnType>
+ implements Configurator.Initializer<ReturnType>,
Configurator.SequencerConfigurator<ReturnType>,
+ Configurator.RepositoryConfigurator<ReturnType>,
Configurator.MimeDetectorConfigurator<ReturnType> {
+
+ private Path sourcesPath;
+ private Path sequencersPath;
+ private Path detectorsPath;
+
+ /**
+ * 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
+ * @param builder the builder object returned from all the methods
+ * @throws IllegalArgumentException if the supplied context reference is null
+ */
+ public Builder( ExecutionContext context,
+ ReturnType builder ) {
+ super(context, builder);
+ }
+
+ public DnaEngine buildDnaEngine() {
+ return new DnaEngine(context, configurationSource);
+ }
+
+ public ConfigurationRepository getConfigurationRepository() {
+ return configurationSource;
+ }
+
+ protected Path sourcesPath() {
+ // Make sure the "dna:sources" node is there
+ if (sourcesPath == null) {
+ Path path = pathFactory().create(this.configurationSource.getPath(),
DnaLexicon.SOURCES);
+ Node node = graph().createIfMissing(path).andReturn();
+ this.sourcesPath = node.getLocation().getPath();
+ }
+ return this.sourcesPath;
+ }
+
+ protected Path sequencersPath() {
+ // Make sure the "dna:sequencers" node is there
+ if (sequencersPath == null) {
+ Path path = pathFactory().create(this.configurationSource.getPath(),
DnaLexicon.SEQUENCERS);
+ Node node = graph().createIfMissing(path).andReturn();
+ this.sequencersPath = node.getLocation().getPath();
+ }
+ return this.sequencersPath;
+ }
+
+ protected Path detectorsPath() {
+ // Make sure the "dna:mimeTypeDetectors" node is there
+ if (detectorsPath == null) {
+ Path path = pathFactory().create(this.configurationSource.getPath(),
DnaLexicon.MIME_TYPE_DETECTORS);
+ Node node = graph().createIfMissing(path).andReturn();
+ this.detectorsPath = node.getLocation().getPath();
+ }
+ return this.detectorsPath;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.Initializer#withConfigurationRepository()
+ */
+ public ChooseClass<RepositorySource,
ConfigRepositoryDetails<ReturnType>> withConfigurationRepository() {
+ return new ConfigurationRepositoryClassChooser<ReturnType>(builder);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.SequencerConfigurator#addSequencer(java.lang.String)
+ */
+ public ChooseClass<Sequencer, SequencerDetails<ReturnType>>
addSequencer( String id ) {
+ CheckArg.isNotEmpty(id, "id");
+ // Now create the "dna:sequencer" node with the supplied id ...
+ Path path = createOrReplaceNode(sequencersPath(), id);
+ SequencerDetails<ReturnType> details = new
GraphSequencerDetails<ReturnType>(path, builder);
+ return new ClassChooser<Sequencer,
SequencerDetails<ReturnType>>(path, details);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.RepositoryConfigurator#addRepository(java.lang.String)
+ */
+ public ChooseClass<RepositorySource, RepositoryDetails<ReturnType>>
addRepository( String id ) {
+ CheckArg.isNotEmpty(id, "id");
+ // Now create the "dna:source" node with the supplied id ...
+ Path path = createOrReplaceNode(sourcesPath(), id);
+ RepositoryDetails<ReturnType> details = new
GraphRepositoryDetails<ReturnType>(path, builder);
+ return new ClassChooser<RepositorySource,
RepositoryDetails<ReturnType>>(path, details);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.RepositoryConfigurator#addRepository(org.jboss.dna.graph.connector.RepositorySource)
+ */
+ public ReturnType addRepository( RepositorySource source ) {
+ CheckArg.isNotNull(source, "source");
+ CheckArg.isNotEmpty(source.getName(), "source.getName()");
+ String name = source.getName();
+ RepositoryDetails<ReturnType> details =
addRepository(source.getName()).usingClass(source.getClass().getName())
+
.loadedFromClasspath();
+ // Record all of the bean properties ...
+ Path sourcePath = pathFactory().create(sourcesPath(), name);
+ recordBeanPropertiesInGraph(sourcePath, source);
+ return details.and();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see
org.jboss.dna.repository.Configurator.MimeDetectorConfigurator#addMimeTypeDetector(java.lang.String)
+ */
+ public ChooseClass<MimeTypeDetector,
MimeTypeDetectorDetails<ReturnType>> addMimeTypeDetector( String id ) {
+ CheckArg.isNotEmpty(id, "id");
+ // Now create the "dna:sequencer" node with the supplied id ...
+ Path detectorPath = createOrReplaceNode(detectorsPath(), id);
+ MimeTypeDetectorDetails<ReturnType> details = new
GraphMimeTypeDetectorDetails<ReturnType>(detectorPath, builder);
+ return new ClassChooser<MimeTypeDetector,
MimeTypeDetectorDetails<ReturnType>>(detectorPath, details);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.repository.Configurator#nameFor(java.lang.String)
+ */
+ @Override
+ protected Name nameFor( String name ) {
+ Name result = NAMES_TO_MAP.get(name);
+ if (result == null) result =
context.getValueFactories().getNameFactory().create(name);
+ return result;
+ }
+ }
+
+}
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-30
04:32:26 UTC (rev 866)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -70,7 +70,7 @@
public static final String CONFIGURATION_REPOSITORY_NAME =
"dna:configuration";
- private final DnaConfiguration.ConfigurationRepository configuration;
+ private final Configurator.ConfigurationRepository configuration;
private final ConfigurationScanner scanner;
private final Problems problems;
private final ExecutionContext context;
@@ -84,14 +84,15 @@
private final RepositoryConnectionFactory connectionFactory;
- DnaEngine( DnaConfiguration configuration ) {
+ DnaEngine( ExecutionContext context,
+ Configurator.ConfigurationRepository configuration ) {
this.problems = new SimpleProblems();
// Use the configuration's context ...
- this.context = configuration.context();
+ this.context = context;
// And set up the scanner ...
- this.configuration = configuration.configurationSource;
+ this.configuration = configuration;
this.scanner = new ConfigurationScanner(this.problems, this.context,
this.configuration);
// Add the configuration source to the repository library ...
@@ -211,11 +212,11 @@
protected class ConfigurationScanner {
private final Problems problems;
private final ExecutionContext context;
- private final DnaConfiguration.ConfigurationRepository configurationRepository;
+ private final Configurator.ConfigurationRepository configurationRepository;
protected ConfigurationScanner( Problems problems,
ExecutionContext context,
- DnaConfiguration.ConfigurationRepository
configurationRepository ) {
+ Configurator.ConfigurationRepository
configurationRepository ) {
this.problems = problems;
this.context = context;
this.configurationRepository = configurationRepository;
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-30
04:32:26 UTC (rev 866)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/DnaConfigurationTest.java 2009-04-30
15:31:52 UTC (rev 867)
@@ -85,8 +85,8 @@
.and()
.save();
assertThat(config, is(notNullValue()));
- assertThat(config.configurationSource.getRepositorySource(),
is(instanceOf(InMemoryRepositorySource.class)));
- InMemoryRepositorySource source =
(InMemoryRepositorySource)config.configurationSource.getRepositorySource();
+ assertThat(config.configurationRepository().getRepositorySource(),
is(instanceOf(InMemoryRepositorySource.class)));
+ InMemoryRepositorySource source =
(InMemoryRepositorySource)config.configurationRepository().getRepositorySource();
assertThat(source.getName(), is("repository name"));
assertThat(source.getRetryLimit(), is(5));
}
@@ -287,7 +287,8 @@
.usingClass(ExtensionBasedMimeTypeDetector.class)
.describedAs("default detector");
configuration.addSequencer("sequencerA")
- .usingClass(MockSequencerA.class)
+ .usingClass(MockSequencerA.class.getName())
+ .loadedFromClasspath()
.named("The (Main) Sequencer")
.describedAs("Mock Sequencer A")
.sequencingFrom("/foo/source")