Author: rhauch
Date: 2008-05-06 10:57:52 -0400 (Tue, 06 May 2008)
New Revision: 115
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerLibrary.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/AbstractSessionFactory.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleSessionFactory.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/MockExecutionContext.java
trunk/docs/examples/
trunk/docs/examples/getting_started/
trunk/docs/examples/getting_started/pom.xml
trunk/docs/examples/getting_started/sequencers/
trunk/docs/examples/getting_started/sequencers/.classpath
trunk/docs/examples/getting_started/sequencers/.project
trunk/docs/examples/getting_started/sequencers/pom.xml
trunk/docs/examples/getting_started/sequencers/src/
trunk/docs/examples/getting_started/sequencers/src/main/
trunk/docs/examples/getting_started/sequencers/src/main/assembly/
trunk/docs/examples/getting_started/sequencers/src/main/assembly/basic.xml
trunk/docs/examples/getting_started/sequencers/src/main/config/
trunk/docs/examples/getting_started/sequencers/src/main/config/run.sh
trunk/docs/examples/getting_started/sequencers/src/main/java/
trunk/docs/examples/getting_started/sequencers/src/main/java/org/
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/ConsoleInput.java
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/ImageInfo.java
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/UserInterface.java
trunk/docs/examples/getting_started/sequencers/src/main/resources/
trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.gif
trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.jpg
trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.pict
trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.png
trunk/docs/examples/getting_started/sequencers/src/main/resources/jackrabbitConfig.xml
trunk/docs/examples/getting_started/sequencers/src/main/resources/jackrabbitNodeTypes.cnd
trunk/docs/examples/getting_started/sequencers/src/main/resources/log4j.properties
trunk/docs/examples/getting_started/sequencers/src/test/
trunk/docs/examples/getting_started/sequencers/src/test/java/
trunk/docs/examples/getting_started/sequencers/src/test/java/org/
trunk/docs/examples/getting_started/sequencers/src/test/java/org/jboss/
trunk/docs/examples/getting_started/sequencers/src/test/java/org/jboss/example/
trunk/docs/examples/getting_started/sequencers/src/test/java/org/jboss/example/dna/
trunk/docs/examples/getting_started/sequencers/src/test/java/org/jboss/example/dna/sequencers/
trunk/docs/examples/getting_started/sequencers/src/test/java/org/jboss/example/dna/sequencers/SequencingClientTest.java
trunk/docs/getting_started/.project
Removed:
trunk/dna-repository/src/main/java/org/jboss/dna/services/
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/SimpleExecutionContext.java
trunk/docs/.project
Modified:
trunk/dna-common/src/main/java/org/jboss/dna/common/component/ComponentLibrary.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryI18n.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/observation/ObservationService.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerPathExpression.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencingService.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/JcrTools.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/JndiSessionFactory.java
trunk/dna-repository/src/main/resources/org/jboss/dna/repository/RepositoryI18n.properties
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencerPathExpressionTest.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencingServiceTest.java
trunk/pom.xml
Log:
Added example, changed some of the implementation classes to be used more easily.
Modified:
trunk/dna-common/src/main/java/org/jboss/dna/common/component/ComponentLibrary.java
===================================================================
---
trunk/dna-common/src/main/java/org/jboss/dna/common/component/ComponentLibrary.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-common/src/main/java/org/jboss/dna/common/component/ComponentLibrary.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -202,7 +202,7 @@
// Don't use ClassLoader.loadClass(String), as it doesn't properly
initialize the class
// (specifically static initializers may not be called)
Class<?> componentClass = Class.forName(config.getComponentClassname(),
true, classLoader);
- newInstance = (ComponentType)componentClass.newInstance();
+ newInstance = doCreateInstance(componentClass);
if (newInstance instanceof Component) {
((Component<ConfigType>)newInstance).setConfiguration(config);
}
@@ -216,6 +216,19 @@
}
/**
+ * Method that instantiates the supplied class. This method can be overridden by
subclasses that may need to wrap or adapt the
+ * instance to be a ComponentType.
+ * @param componentClass
+ * @return
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ */
+ @SuppressWarnings( "unchecked" )
+ protected ComponentType doCreateInstance( Class<?> componentClass ) throws
InstantiationException, IllegalAccessException {
+ return (ComponentType)componentClass.newInstance();
+ }
+
+ /**
* Find the index for the matching {@link #configurations configuration} and {@link
#sequencerInstances sequencer}.
* @param config the configuration; may not be null
* @return the index, or -1 if not found
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryI18n.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryI18n.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryI18n.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -30,85 +30,91 @@
*/
public final class RepositoryI18n {
- public static I18n invalidStateString;
- public static I18n serviceShutdowAndMayNotBeStarted;
- public static I18n serviceShutdowAndMayNotBePaused;
- public static I18n unableToFindRepositoryInJndi;
- public static I18n errorProcessingEvents;
- public static I18n errorFindingPropertyNameInPropertyAddedEvent;
- public static I18n errorFindingPropertyNameInPropertyChangedEvent;
- public static I18n errorFindingPropertyNameInPropertyRemovedEvent;
+ public static I18n invalidStateString;
+ public static I18n serviceShutdowAndMayNotBeStarted;
+ public static I18n serviceShutdowAndMayNotBePaused;
+ public static I18n unableToFindRepositoryInJndi;
+ public static I18n unableToRegisterRepositoryInJndi;
+ public static I18n unableToUnregisterRepositoryInJndi;
+ public static I18n unableToRemoveRepository;
+ public static I18n unableToFindRepositoryWithName;
+ public static I18n errorProcessingEvents;
+ public static I18n errorFindingPropertyNameInPropertyAddedEvent;
+ public static I18n errorFindingPropertyNameInPropertyChangedEvent;
+ public static I18n errorFindingPropertyNameInPropertyRemovedEvent;
- public static I18n unableToObtainJsr94RuleAdministrator;
- public static I18n errorUsingJsr94RuleAdministrator;
- public static I18n unableToObtainJsr94ServiceProvider;
- public static I18n errorAddingOrUpdatingRuleSet;
- public static I18n errorRollingBackRuleSetAfterUpdateFailed;
- public static I18n errorReadingRulesAndProperties;
- public static I18n errorDeregisteringRuleSetBeforeUpdatingIt;
- public static I18n errorRecreatingRuleSet;
- public static I18n errorRemovingRuleSet;
- public static I18n errorRemovingRuleSetUponShutdown;
- public static I18n unableToFindRuleSet;
- public static I18n errorExecutingRuleSetWithGlobalsAndFacts;
- public static I18n unableToBuildRuleSetRegularExpressionPattern;
+ public static I18n unableToObtainJsr94RuleAdministrator;
+ public static I18n errorUsingJsr94RuleAdministrator;
+ public static I18n unableToObtainJsr94ServiceProvider;
+ public static I18n errorAddingOrUpdatingRuleSet;
+ public static I18n errorRollingBackRuleSetAfterUpdateFailed;
+ public static I18n errorReadingRulesAndProperties;
+ public static I18n errorDeregisteringRuleSetBeforeUpdatingIt;
+ public static I18n errorRecreatingRuleSet;
+ public static I18n errorRemovingRuleSet;
+ public static I18n errorRemovingRuleSetUponShutdown;
+ public static I18n unableToFindRuleSet;
+ public static I18n errorExecutingRuleSetWithGlobalsAndFacts;
+ public static I18n unableToBuildRuleSetRegularExpressionPattern;
- public static I18n errorObtainingSessionToRepositoryWorkspace;
- public static I18n errorWritingProblemsOnRuleSet;
+ public static I18n errorObtainingSessionToRepositoryWorkspace;
+ public static I18n errorWritingProblemsOnRuleSet;
- public static I18n sequencingServiceName;
- public static I18n unableToChangeExecutionContextWhileRunning;
- public static I18n unableToStartSequencingServiceWithoutExecutionContext;
- public static I18n errorWhileSequencingNode;
- public static I18n errorInRepositoryWhileSequencingNode;
- public static I18n errorFindingSequencersToRunAgainstNode;
- public static I18n errorInRepositoryWhileFindingSequencersToRunAgainstNode;
- public static I18n executionContextHasBeenClosed;
- public static I18n sequencerTask;
- public static I18n sequencerSubtask;
- public static I18n unableToFindPropertyForSequencing;
- public static I18n sequencingPropertyOnNode;
- public static I18n writingOutputSequencedFromPropertyOnNodes;
+ public static I18n sequencingServiceName;
+ public static I18n unableToChangeExecutionContextWhileRunning;
+ public static I18n unableToStartSequencingServiceWithoutExecutionContext;
+ public static I18n errorWhileSequencingNode;
+ public static I18n errorInRepositoryWhileSequencingNode;
+ public static I18n errorFindingSequencersToRunAgainstNode;
+ public static I18n errorInRepositoryWhileFindingSequencersToRunAgainstNode;
+ public static I18n executionContextHasBeenClosed;
+ public static I18n sequencerTask;
+ public static I18n sequencerSubtask;
+ public static I18n unableToFindPropertyForSequencing;
+ public static I18n sequencingPropertyOnNode;
+ public static I18n writingOutputSequencedFromPropertyOnNodes;
- public static I18n errorReadingPropertiesFromContainerNode;
- public static I18n requiredPropertyOnNodeWasExpectedToBeStringValue;
- public static I18n optionalPropertyOnNodeWasExpectedToBeStringValue;
- public static I18n requiredPropertyOnNodeWasExpectedToBeStringArrayValue;
- public static I18n optionalPropertyOnNodeWasExpectedToBeStringArrayValue;
- public static I18n requiredPropertyOnNodeCouldNotBeRead;
- public static I18n optionalPropertyOnNodeCouldNotBeRead;
- public static I18n requiredPropertyIsMissingFromNode;
- public static I18n errorGettingRequiredPropertyFromNode;
- public static I18n errorGettingOptionalPropertyFromNode;
- public static I18n errorClosingBinaryStreamForPropertyFromNode;
- public static I18n requiredNodeDoesNotExistRelativeToNode;
- public static I18n errorGettingNodeRelativeToNode;
- public static I18n unknownPropertyValueType;
+ public static I18n errorReadingPropertiesFromContainerNode;
+ public static I18n requiredPropertyOnNodeWasExpectedToBeStringValue;
+ public static I18n optionalPropertyOnNodeWasExpectedToBeStringValue;
+ public static I18n requiredPropertyOnNodeWasExpectedToBeStringArrayValue;
+ public static I18n optionalPropertyOnNodeWasExpectedToBeStringArrayValue;
+ public static I18n requiredPropertyOnNodeCouldNotBeRead;
+ public static I18n optionalPropertyOnNodeCouldNotBeRead;
+ public static I18n requiredPropertyIsMissingFromNode;
+ public static I18n errorGettingRequiredPropertyFromNode;
+ public static I18n errorGettingOptionalPropertyFromNode;
+ public static I18n errorClosingBinaryStreamForPropertyFromNode;
+ public static I18n requiredNodeDoesNotExistRelativeToNode;
+ public static I18n errorGettingNodeRelativeToNode;
+ public static I18n unknownPropertyValueType;
- public static I18n pathExpressionIsInvalid;
- public static I18n pathExpressionMayNotBeBlank;
- public static I18n pathExpressionHasInvalidSelect;
- public static I18n pathExpressionHasInvalidMatch;
+ public static I18n pathExpressionIsInvalid;
+ public static I18n pathExpressionMayNotBeBlank;
+ public static I18n pathExpressionHasInvalidSelect;
+ public static I18n pathExpressionHasInvalidMatch;
- public static I18n invalidRepositoryNodePath;
+ public static I18n
errorUnregisteringWorkspaceListenerWhileShuttingDownObservationService;
- static {
- try {
- I18n.initialize(RepositoryI18n.class);
- } catch (final Exception err) {
- System.err.println(err);
- }
- }
+ public static I18n invalidRepositoryNodePath;
- public static Set<Locale> getLocalizationProblemLocales() {
- return I18n.getLocalizationProblemLocales(RepositoryI18n.class);
- }
+ static {
+ try {
+ I18n.initialize(RepositoryI18n.class);
+ } catch (final Exception err) {
+ System.err.println(err);
+ }
+ }
- public static Set<String> getLocalizationProblems() {
- return I18n.getLocalizationProblems(RepositoryI18n.class);
- }
+ public static Set<Locale> getLocalizationProblemLocales() {
+ return I18n.getLocalizationProblemLocales(RepositoryI18n.class);
+ }
- public static Set<String> getLocalizationProblems( Locale locale ) {
- return I18n.getLocalizationProblems(RepositoryI18n.class, locale);
- }
+ public static Set<String> getLocalizationProblems() {
+ return I18n.getLocalizationProblems(RepositoryI18n.class);
+ }
+
+ public static Set<String> getLocalizationProblems( Locale locale ) {
+ return I18n.getLocalizationProblems(RepositoryI18n.class, locale);
+ }
}
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/observation/ObservationService.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/observation/ObservationService.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/observation/ObservationService.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -109,6 +109,15 @@
/**
* {@inheritDoc}
*/
+ @Override
+ protected void doShutdown( State fromState ) {
+ super.doShutdown(fromState);
+ shutdownService();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public boolean awaitTermination( long timeout, TimeUnit unit ) {
return true;
}
@@ -119,6 +128,7 @@
private ProblemLog problemLog = new DefaultProblemLog();
private final Statistics statistics = new Statistics();
private final SessionFactory sessionFactory;
+ private final CopyOnWriteArrayList<WorkspaceListener> workspaceListeners = new
CopyOnWriteArrayList<WorkspaceListener>();
private final CopyOnWriteArrayList<EventListener> eventListeners = new
CopyOnWriteArrayList<EventListener>();
private final CopyOnWriteArrayList<NodeChangeListener> nodeChangeListeners =
new CopyOnWriteArrayList<NodeChangeListener>();
private final Administrator administrator = new Administrator();
@@ -200,6 +210,17 @@
return this.nodeChangeListeners.remove(listener);
}
+ protected void shutdownService() {
+ // Unregister all listeners ...
+ for (WorkspaceListener listener : this.workspaceListeners) {
+ try {
+ listener.unregister();
+ } catch (RepositoryException e) {
+
this.logger.error(RepositoryI18n.errorUnregisteringWorkspaceListenerWhileShuttingDownObservationService);
+ }
+ }
+ }
+
/**
* Monitor the supplied workspace for events of the given type on any node at or
under the supplied path.
* <p>
@@ -262,6 +283,7 @@
throws RepositoryException {
WorkspaceListener listener = new WorkspaceListener(repositoryWorkspaceName,
eventTypes, absolutePath, isDeep, uuids, nodeTypeNames, noLocal);
listener.register();
+ this.workspaceListeners.add(listener);
return listener;
}
@@ -315,6 +337,10 @@
return monitor(repositoryWorkspaceName, WorkspaceListener.DEFAULT_ABSOLUTE_PATH,
eventTypes, WorkspaceListener.DEFAULT_IS_DEEP, null, nodeTypeNames,
WorkspaceListener.DEFAULT_NO_LOCAL);
}
+ protected void unregisterListener( WorkspaceListener listener ) {
+ if (listener != null) this.workspaceListeners.remove(listener);
+ }
+
/**
* From section 2.8.8 of the JSR-170 specification:
* <p>
@@ -564,6 +590,7 @@
this.session.logout();
} finally {
this.session = null;
+ unregisterListener(this);
}
return this;
}
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerLibrary.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerLibrary.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerLibrary.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,51 @@
+/*
+ * 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.sequencers;
+
+import org.jboss.dna.common.component.ComponentLibrary;
+import org.jboss.dna.spi.sequencers.StreamSequencer;
+
+/**
+ * @author Randall Hauch
+ */
+public class SequencerLibrary extends ComponentLibrary<Sequencer, SequencerConfig>
{
+
+ /**
+ *
+ */
+ public SequencerLibrary() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Sequencer doCreateInstance( Class<?> componentClass ) throws
InstantiationException, IllegalAccessException {
+ Object sequencerImpl = componentClass.newInstance();
+ if (sequencerImpl instanceof StreamSequencer) {
+ sequencerImpl = new StreamSequencerAdapter((StreamSequencer)sequencerImpl);
+ }
+ return (Sequencer)sequencerImpl;
+ }
+
+}
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerPathExpression.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerPathExpression.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencerPathExpression.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -265,8 +265,9 @@
}
// Order is important here
- expression = expression.replaceAll("[*]", "[^/]*");
- expression = expression.replaceAll("[/]{2,}", "(/[^/]*)*/");
+ expression = expression.replaceAll("[*]([^/])",
"[^/$1]*$1");
+ expression = expression.replaceAll("(?<!\\[\\^/\\])[*]",
"[^/]*");
+ expression = expression.replaceAll("[/]{2,}",
"(?:/[^/]*)*/");
return expression;
}
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencingService.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencingService.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/sequencers/SequencingService.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -29,6 +29,7 @@
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
@@ -185,7 +186,7 @@
}
private ExecutionContext executionContext;
- private ComponentLibrary<Sequencer, SequencerConfig> sequencerLibrary = new
ComponentLibrary<Sequencer, SequencerConfig>();
+ private SequencerLibrary sequencerLibrary = new SequencerLibrary();
private Selector sequencerSelector = DEFAULT_SEQUENCER_SELECTOR;
private NodeFilter nodeFilter = DEFAULT_NODE_FILTER;
private ExecutorService executorService;
@@ -431,12 +432,16 @@
for (final NodeChange changedNode : changes) {
// Only care about new nodes or nodes that have new/changed properies ...
if (filter.accept(changedNode)) {
- this.executorService.execute(new Runnable() {
+ try {
+ this.executorService.execute(new Runnable() {
- public void run() {
- processChangedNode(changedNode);
- }
- });
+ public void run() {
+ processChangedNode(changedNode);
+ }
+ });
+ } catch (RejectedExecutionException e) {
+ // The executor service has been shut down, so do nothing with this
set of changes
+ }
}
}
}
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/AbstractSessionFactory.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/AbstractSessionFactory.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/AbstractSessionFactory.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,218 @@
+/*
+ * 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.util;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.jcr.Credentials;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import org.jboss.dna.common.SystemFailureException;
+import org.jboss.dna.common.util.ArgCheck;
+
+/**
+ * A SessionFactory implementation that creates {@link Session} instances using {@link
Repository} instances.
+ * <p>
+ * This factory using a naming convention where the name supplied to the {@link
#createSession(String)} contains both the name of
+ * the repository and the name of the workspace. Typically, this is
<i><code>repositoryName/workspaceName</code></i>, where
+ * <code>repositoryName</code> is the name under which the Repository
instance was bound, and <code>workspaceName</code> is
+ * the name of the workspace. Note that this method looks for the last delimiter in the
whole name to distinguish between the
+ * repository and workspace names.
+ * </p>
+ * <p>
+ * For example, if
"<code>java:comp/env/repository/dataRepository/myWorkspace</code>"
is passed to the
+ * {@link #createSession(String)} method, this factory will look for a {@link Repository}
instance registered with the name
"<code>java:comp/env/repository/dataRepository</code>"
+ * and use it to {@link Repository#login(String) create a session} to the workspace named
"<code>myWorkspace</code>".
+ * </p>
+ * <p>
+ * By default, this factory creates an anonymous JCR session. To use sessions with
specific {@link Credentials}, simply
+ * {@link #registerCredentials(String, Credentials) register} credentials for the
appropriate repository/workspace name. For
+ * security reasons, it is not possible to retrieve the Credentials once registered with
this factory.
+ * </p>
+ * @author Randall Hauch
+ */
+public abstract class AbstractSessionFactory implements SessionFactory {
+
+ protected static char[] DEFAULT_DELIMITERS = new char[] {'/'};
+
+ private final char[] workspaceDelims;
+ private final String workspaceDelimsRegexCharacterSet;
+ private final Map<String, Credentials> credentials = new
ConcurrentHashMap<String, Credentials>();
+
+ /**
+ * Create an instance of the factory with the default delimiters.
+ */
+ public AbstractSessionFactory() {
+ this(null);
+ }
+
+ /**
+ * Create an instance of the factory by supplying naming context and the characters
that may be used to delimit the workspace
+ * name from the repository name.
+ * @param workspaceDelimiters the delimiters, or null/empty if the default delimiter
of '/' should be used.
+ * @throws IllegalArgumentException if the context parameter is null
+ */
+ public AbstractSessionFactory( char... workspaceDelimiters ) {
+ this.workspaceDelims = (workspaceDelimiters == null || workspaceDelimiters.length
== 0) ? DEFAULT_DELIMITERS : workspaceDelimiters;
+ StringBuilder sb = new StringBuilder();
+ for (char delim : this.workspaceDelims) {
+ switch (delim) {
+ case '\\':
+ sb.append("\\");
+ break;
+ // case '[' : sb.append("\\["); break;
+ case ']':
+ sb.append("\\]");
+ break;
+ case '-':
+ sb.append("\\-");
+ break;
+ case '^':
+ sb.append("\\^");
+ break;
+ default:
+ sb.append(delim);
+ }
+ }
+ this.workspaceDelimsRegexCharacterSet = sb.toString();
+ }
+
+ /**
+ * Convenience method to bind a repository in JNDI. Repository instances can be bound
into JNDI using any technique, so this
+ * method need not be used. <i>Note that the name should not contain the
workspace part.</i>
+ * @param name the name of the repository, without the workspace name component.
+ * @param repository the repository to be bound, or null if an existing repository
should be unbound.
+ */
+ public void registerRepository( String name, Repository repository ) {
+ assert name != null;
+ // Remove all trailing delimiters ...
+ name = name.replaceAll("[" + this.workspaceDelimsRegexCharacterSet +
"]+$", "");
+ if (repository != null) {
+ this.doRegisterRepository(name, repository);
+ } else {
+ this.doUnregisterRepository(name);
+ }
+ }
+
+ protected abstract void doRegisterRepository( String name, Repository repository )
throws SystemFailureException;
+
+ protected abstract void doUnregisterRepository( String name ) throws
SystemFailureException;
+
+ protected abstract Repository findRegisteredRepository( String name ) throws
SystemFailureException;
+
+ /**
+ * Register the credentials for the repository and workspace given by the supplied
name, username and password. This is
+ * equivalent to calling <code>registerCredentials(name, new
SimpleCredentials(username,password))</code>, although if
+ * <code>username</code> is null then this is equivalent to
<code>registerCredentials(name,null)</code>.
+ * @param name the name of the repository and workspace
+ * @param username the username to use, or null if the existing credentials for the
named workspace should be removed
+ * @param password the password, may be null or empty
+ * @return true if this overwrote existing credentials
+ * @see #registerCredentials(String, Credentials)
+ * @see #removeCredentials(String)
+ */
+ public boolean registerCredentials( String name, String username, char[] password )
{
+ if (password == null && username != null) password = new char[] {};
+ Credentials creds = username == null ? null : new SimpleCredentials(username,
password);
+ return registerCredentials(name, creds);
+ }
+
+ /**
+ * Register the credentials to be used for the named repository and workspace. Use
the same name as used to
+ * {@link #createSession(String) create sessions}.
+ * @param name the name of the repository and workspace
+ * @param credentials the credentials to use, or null if the existing credentials for
the named workspace should be removed
+ * @return true if this overwrote existing credentials
+ * @see #registerCredentials(String, String, char[])
+ * @see #removeCredentials(String)
+ */
+ public boolean registerCredentials( String name, Credentials credentials ) {
+ boolean foundExisting = false;
+ name = name != null ? name.trim() : null;
+ if (credentials == null) {
+ foundExisting = this.credentials.remove(name) != null;
+ } else {
+ foundExisting = this.credentials.put(name, credentials) != null;
+ }
+ return foundExisting;
+ }
+
+ /**
+ * Remove any credentials associated with the named repository and workspace. This is
equivalent to calling
+ * <code>registerCredentials(name,null)</code>.
+ * @param name the name of the repository and workspace
+ * @return true if existing credentials were found and removed, or false if no such
credentials existed
+ * @see #registerCredentials(String, Credentials)
+ */
+ public boolean removeCredentials( String name ) {
+ return registerCredentials(name, null);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Session createSession( String name ) throws RepositoryException {
+ ArgCheck.isNotNull(name, "session name");
+ name = name.trim();
+ // Look up the Repository object in JNDI ...
+ String repositoryName = getRepositoryName(name);
+ Repository repository = findRegisteredRepository(repositoryName);
+
+ // Determine the name of the workspace ...
+ String workspaceName = getWorkspaceName(name);
+
+ // Look up any credentials, which may be null ...
+ Credentials creds = this.credentials.get(name);
+
+ // Create a session to the specified workspace and using the credentials (either
or both may be null) ...
+ return repository.login(creds, workspaceName);
+ }
+
+ protected String getWorkspaceName( String name ) {
+ assert name != null;
+ int index = getIndexOfLastWorkspaceDelimiter(name);
+ if (index == -1) return null;
+ if ((index + 1) == name.length()) return null; // delim is the last character
+ return name.substring(index + 1);
+ }
+
+ protected String getRepositoryName( String name ) {
+ assert name != null;
+ int index = getIndexOfLastWorkspaceDelimiter(name);
+ if (index == -1) return name; // no delim
+ if ((index + 1) == name.length()) return name.substring(0, index); // delim as
last character
+ return name.substring(0, index);
+ }
+
+ protected int getIndexOfLastWorkspaceDelimiter( String name ) {
+ int index = -1;
+ for (char delim : this.workspaceDelims) {
+ int i = name.lastIndexOf(delim);
+ index = Math.max(index, i);
+ }
+ return index;
+ }
+
+}
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/JcrTools.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/JcrTools.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/JcrTools.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -268,20 +268,33 @@
}
public Node findOrCreateNode( Session session, String path ) throws
RepositoryException {
+ return findOrCreateNode(session, path, null, null);
+ }
+
+ public Node findOrCreateNode( Session session, String path, String nodeType ) throws
RepositoryException {
+ return findOrCreateNode(session, path, nodeType, nodeType);
+ }
+
+ public Node findOrCreateNode( Session session, String path, String defaultNodeType,
String finalNodeType ) throws RepositoryException {
Node root = session.getRootNode();
+ return findOrCreateNode(session, root, path, defaultNodeType, finalNodeType);
+ }
+
+ public Node findOrCreateNode( Session session, Node parentNode, String path, String
defaultNodeType, String finalNodeType ) throws RepositoryException {
// Remove leading and trailing slashes ...
String relPath = path.replaceAll("^/+",
"").replaceAll("/+$", "");
// Look for the node first ...
try {
- return root.getNode(relPath);
+ return parentNode.getNode(relPath);
} catch (PathNotFoundException e) {
// continue
}
// Create the node, which has to be done segment by segment ...
String[] pathSegments = relPath.split("/");
- Node node = root;
- for (String pathSegment : pathSegments) {
+ Node node = parentNode;
+ for (int i = 0, len = pathSegments.length; i != len; ++i) {
+ String pathSegment = pathSegments[i];
pathSegment = pathSegment.trim();
if (pathSegment.length() == 0) continue;
if (node.hasNode(pathSegment)) {
@@ -291,10 +304,24 @@
// Make sure there is no index on the final segment ...
String pathSegmentWithNoIndex =
pathSegment.replaceAll("(\\[\\d+\\])+$", "");
// Create the node ...
- node = node.addNode(pathSegmentWithNoIndex);
+ String nodeType = defaultNodeType;
+ if (i == len - 1 && finalNodeType != null) nodeType =
finalNodeType;
+ if (nodeType != null) {
+ node = node.addNode(pathSegmentWithNoIndex, nodeType);
+ } else {
+ node = node.addNode(pathSegmentWithNoIndex);
+ }
}
}
return node;
}
+ public Node findOrCreateChild( Session session, Node parent, String name ) throws
RepositoryException {
+ return findOrCreateChild(session, parent, name, null);
+ }
+
+ public Node findOrCreateChild( Session session, Node parent, String name, String
nodeType ) throws RepositoryException {
+ return findOrCreateNode(session, parent, name, nodeType, nodeType);
+ }
+
}
Modified:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/JndiSessionFactory.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/JndiSessionFactory.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/JndiSessionFactory.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -22,13 +22,9 @@
package org.jboss.dna.repository.util;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import javax.jcr.Credentials;
import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
@@ -58,14 +54,9 @@
* </p>
* @author Randall Hauch
*/
-public class JndiSessionFactory implements SessionFactory {
+public class JndiSessionFactory extends AbstractSessionFactory {
- protected static char[] DEFAULT_DELIMITERS = new char[] {'/'};
-
- private final char[] workspaceDelims;
- private final String workspaceDelimsRegexCharacterSet;
private final Context context;
- private final Map<String, Credentials> credentials = new
ConcurrentHashMap<String, Credentials>();
/**
* Create an instance of the factory by creating a new {@link InitialContext}. This
is equivalent to calling
@@ -104,146 +95,44 @@
* @throws IllegalArgumentException if the context parameter is null
*/
public JndiSessionFactory( Context context, char... workspaceDelimiters ) {
+ super(workspaceDelimiters);
ArgCheck.isNotNull(context, "initial context");
this.context = context;
- this.workspaceDelims = (workspaceDelimiters == null || workspaceDelimiters.length
== 0) ? DEFAULT_DELIMITERS : workspaceDelimiters;
- StringBuilder sb = new StringBuilder();
- for (char delim : this.workspaceDelims) {
- switch (delim) {
- case '\\':
- sb.append("\\");
- break;
- // case '[' : sb.append("\\["); break;
- case ']':
- sb.append("\\]");
- break;
- case '-':
- sb.append("\\-");
- break;
- case '^':
- sb.append("\\^");
- break;
- default:
- sb.append(delim);
- }
- }
- this.workspaceDelimsRegexCharacterSet = sb.toString();
}
/**
- * Convenience method to bind a repository in JNDI. Repository instances can be bound
into JNDI using any technique, so this
- * method need not be used. <i>Note that the name should not contain the
workspace part.</i>
- * @param name the name of the repository, without the workspace name component.
- * @param repository the repository to be bound, or null if an existing repository
should be unbound.
- * @throws NamingException if there is a problem registering the supplied repository
+ * {@inheritDoc}
*/
- public void registerRepository( String name, Repository repository ) throws
NamingException {
- assert name != null;
- // Remove all trailing delimiters ...
- name = name.replaceAll("[" + this.workspaceDelimsRegexCharacterSet +
"]+$", "");
- if (repository != null) {
+ @Override
+ protected void doRegisterRepository( String name, Repository repository ) throws
SystemFailureException {
+ try {
this.context.bind(name, repository);
- } else {
- this.context.unbind(name);
+ } catch (NamingException e) {
+ throw new
SystemFailureException(RepositoryI18n.unableToRegisterRepositoryInJndi.text(name));
}
}
/**
- * Register the credentials for the repository and workspace given by the supplied
name, username and password. This is
- * equivalent to calling <code>registerCredentials(name, new
SimpleCredentials(username,password))</code>, although if
- * <code>username</code> is null then this is equivalent to
<code>registerCredentials(name,null)</code>.
- * @param name the name of the repository and workspace
- * @param username the username to use, or null if the existing credentials for the
named workspace should be removed
- * @param password the password, may be null or empty
- * @return true if this overwrote existing credentials
- * @see #registerCredentials(String, Credentials)
- * @see #removeCredentials(String)
+ * {@inheritDoc}
*/
- public boolean registerCredentials( String name, String username, char[] password )
{
- if (password == null && username != null) password = new char[] {};
- Credentials creds = username == null ? null : new SimpleCredentials(username,
password);
- return registerCredentials(name, creds);
- }
-
- /**
- * Register the credentials to be used for the named repository and workspace. Use
the same name as used to
- * {@link #createSession(String) create sessions}.
- * @param name the name of the repository and workspace
- * @param credentials the credentials to use, or null if the existing credentials for
the named workspace should be removed
- * @return true if this overwrote existing credentials
- * @see #registerCredentials(String, String, char[])
- * @see #removeCredentials(String)
- */
- public boolean registerCredentials( String name, Credentials credentials ) {
- boolean foundExisting = false;
- name = name != null ? name.trim() : null;
- if (credentials == null) {
- foundExisting = this.credentials.remove(name) != null;
- } else {
- foundExisting = this.credentials.put(name, credentials) != null;
+ @Override
+ protected void doUnregisterRepository( String name ) throws SystemFailureException {
+ try {
+ this.context.unbind(name);
+ } catch (NamingException e) {
+ throw new
SystemFailureException(RepositoryI18n.unableToUnregisterRepositoryInJndi.text(name));
}
- return foundExisting;
}
/**
- * Remove any credentials associated with the named repository and workspace. This is
equivalent to calling
- * <code>registerCredentials(name,null)</code>.
- * @param name the name of the repository and workspace
- * @return true if existing credentials were found and removed, or false if no such
credentials existed
- * @see #registerCredentials(String, Credentials)
- */
- public boolean removeCredentials( String name ) {
- return registerCredentials(name, null);
- }
-
- /**
* {@inheritDoc}
*/
- public Session createSession( String name ) throws RepositoryException {
- ArgCheck.isNotNull(name, "session name");
- name = name.trim();
- // Look up the Repository object in JNDI ...
- String repositoryName = getRepositoryName(name);
- Repository repository = null;
+ @Override
+ protected Repository findRegisteredRepository( String name ) throws
SystemFailureException {
try {
- repository = (Repository)this.context.lookup(repositoryName);
- } catch (NamingException err) {
- throw new
SystemFailureException(RepositoryI18n.unableToFindRepositoryInJndi.text(repositoryName));
+ return (Repository)this.context.lookup(name);
+ } catch (NamingException e) {
+ throw new
SystemFailureException(RepositoryI18n.unableToFindRepositoryInJndi.text(name));
}
-
- // Determine the name of the workspace ...
- String workspaceName = getWorkspaceName(name);
-
- // Look up any credentials, which may be null ...
- Credentials creds = this.credentials.get(name);
-
- // Create a session to the specified workspace and using the credentials (either
or both may be null) ...
- return repository.login(creds, workspaceName);
}
-
- protected String getWorkspaceName( String name ) {
- assert name != null;
- int index = getIndexOfLastWorkspaceDelimiter(name);
- if (index == -1) return null;
- if ((index + 1) == name.length()) return null; // delim is the last character
- return name.substring(index + 1);
- }
-
- protected String getRepositoryName( String name ) {
- assert name != null;
- int index = getIndexOfLastWorkspaceDelimiter(name);
- if (index == -1) return name; // no delim
- if ((index + 1) == name.length()) return name.substring(0, index); // delim as
last character
- return name.substring(0, index);
- }
-
- protected int getIndexOfLastWorkspaceDelimiter( String name ) {
- int index = -1;
- for (char delim : this.workspaceDelims) {
- int i = name.lastIndexOf(delim);
- index = Math.max(index, i);
- }
- return index;
- }
-
}
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleExecutionContext.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,49 @@
+/*
+ * 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.util;
+
+/**
+ * @author Randall Hauch
+ */
+public class SimpleExecutionContext extends SimpleSessionFactory implements
ExecutionContext {
+
+ private final JcrTools tools = new JcrTools();
+
+ public SimpleExecutionContext() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public SessionFactory getSessionFactory() {
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public JcrTools getTools() {
+ return this.tools;
+ }
+
+}
Added:
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleSessionFactory.java
===================================================================
---
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleSessionFactory.java
(rev 0)
+++
trunk/dna-repository/src/main/java/org/jboss/dna/repository/util/SimpleSessionFactory.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,106 @@
+/*
+ * 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.util;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.jcr.Credentials;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.naming.InitialContext;
+import org.jboss.dna.common.SystemFailureException;
+import org.jboss.dna.repository.RepositoryI18n;
+
+/**
+ * A SessionFactory implementation that creates {@link Session} instances using {@link
Repository} instances registered in JNDI.
+ * <p>
+ * This factory using a naming convention where the name supplied to the {@link
#createSession(String)} contains both the name of
+ * the repository and the name of the workspace. Typically, this is
<i><code>repositoryName/workspaceName</code></i>, where
+ * <code>repositoryName</code> is the JNDI name under which the Repository
instance was bound, and <code>workspaceName</code>
+ * is the name of the workspace. Note that this method looks for the last delimiter in
the whole name to distinguish between the
+ * repository and workspace names.
+ * </p>
+ * <p>
+ * For example, if
"<code>java:comp/env/repository/dataRepository/myWorkspace</code>"
is passed to the
+ * {@link #createSession(String)} method, this factory will look for a {@link Repository}
instance registered in JDNI with the
+ * name "<code>java:comp/env/repository/dataRepository</code>" and
use it to {@link Repository#login(String) create a session}
+ * to the workspace named "<code>myWorkspace</code>".
+ * </p>
+ * <p>
+ * By default, this factory creates an anonymous JCR session. To use sessions with
specific {@link Credentials}, simply
+ * {@link #registerCredentials(String, Credentials) register} credentials for the
appropriate repository/workspace name. For
+ * security reasons, it is not possible to retrieve the Credentials once registered with
this factory.
+ * </p>
+ * @author Randall Hauch
+ */
+public class SimpleSessionFactory extends AbstractSessionFactory {
+
+ private final Map<String, Repository> repositories = new
ConcurrentHashMap<String, Repository>();
+
+ /**
+ * Create an instance of the factory by creating a new {@link InitialContext}.
+ */
+ public SimpleSessionFactory() {
+ super();
+ }
+
+ /**
+ * Create an instance of the factory by supplying the characters that may be used to
delimit the workspace name from the
+ * repository name.
+ * @param workspaceDelimiters the delimiters, or null/empty if the default delimiter
of '/' should be used.
+ */
+ public SimpleSessionFactory( char... workspaceDelimiters ) {
+ super(workspaceDelimiters);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doRegisterRepository( String name, Repository repository ) throws
SystemFailureException {
+ this.repositories.put(name, repository);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void doUnregisterRepository( String name ) throws SystemFailureException {
+ if (this.repositories.remove(name) == null) {
+ throw new
SystemFailureException(RepositoryI18n.unableToRemoveRepository.text(name));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Repository findRegisteredRepository( String name ) throws
SystemFailureException {
+ Repository repository = this.repositories.get(name);
+ if (repository == null) {
+ throw new
SystemFailureException(RepositoryI18n.unableToFindRepositoryWithName.text(name));
+ }
+ return repository;
+ }
+
+}
Modified:
trunk/dna-repository/src/main/resources/org/jboss/dna/repository/RepositoryI18n.properties
===================================================================
---
trunk/dna-repository/src/main/resources/org/jboss/dna/repository/RepositoryI18n.properties 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/main/resources/org/jboss/dna/repository/RepositoryI18n.properties 2008-05-06
14:57:52 UTC (rev 115)
@@ -2,6 +2,10 @@
serviceShutdowAndMayNotBeStarted = The {0} has been shutdown and may not be (re)started
serviceShutdowAndMayNotBePaused = The {0} has been shutdown and my not be paused
unableToFindRepositoryInJndi = Unable to find a JCR repository in JNDI at '{0}'
+unableToRegisterRepositoryInJndi = Unable to register a JCR repository in JNDI at
'{0}'
+unableToUnregisterRepositoryInJndi = Unable to unregister a JCR repository at JNDI at
'{0}'
+unableToRemoveRepository = Unable to remove a JCR repository named '{0}'
+unableToFindRepositoryWithName = Unable to find a JCR repository named '{0}'
errorProcessingEvents = Error processing events from {0}
errorFindingPropertyNameInPropertyAddedEvent = Error finding the name of the added
property in the event path {0}
errorFindingPropertyNameInPropertyChangedEvent = Error finding the name of the changed
property in the event path {0}
@@ -58,4 +62,6 @@
pathExpressionHasInvalidSelect = Invalid select expression '{0}' in the path
expression '{1}=>{2}'
pathExpressionHasInvalidMatch = Invalid match expression '{0}' in the path
expression '{1}=>{2}'
+errorUnregisteringWorkspaceListenerWhileShuttingDownObservationService = Error
unregistering workspace listener while shutting down observation service
+
invalidRepositoryNodePath = The repository node path '{0}' is not valid: {1}
Modified:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencerPathExpressionTest.java
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencerPathExpressionTest.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencerPathExpressionTest.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -177,9 +177,9 @@
assertThat(expr.replaceXPathPatterns("/a/(b/c)[(d|e)/(f|g)/@something]"),
is("/a/(b/c)/(d|e)/(f|g)/@something"));
assertThat(expr.replaceXPathPatterns("/a/*/f"),
is("/a/[^/]*/f"));
- assertThat(expr.replaceXPathPatterns("/a//f"),
is("/a(/[^/]*)*/f"));
- assertThat(expr.replaceXPathPatterns("/a///f"),
is("/a(/[^/]*)*/f"));
- assertThat(expr.replaceXPathPatterns("/a/////f"),
is("/a(/[^/]*)*/f"));
+ assertThat(expr.replaceXPathPatterns("/a//f"),
is("/a(?:/[^/]*)*/f"));
+ assertThat(expr.replaceXPathPatterns("/a///f"),
is("/a(?:/[^/]*)*/f"));
+ assertThat(expr.replaceXPathPatterns("/a/////f"),
is("/a(?:/[^/]*)*/f"));
}
protected void assertNotMatches( SequencerPathExpression.Matcher matcher ) {
@@ -235,6 +235,21 @@
}
@Test
+ public void shouldMatchExpressionsWithFilenameLikeWildcardSelection() {
+ expr = SequencerPathExpression.compile("/a/*.txt[@something] =>
.");
+ assertMatches(expr.matcher("/a/b.txt/@something"),
"/a/b.txt", "/a/b.txt");
+ assertNotMatches(expr.matcher("/a/b.tx/@something"));
+
+ expr = SequencerPathExpression.compile("/a/*.txt/c[@something] =>
.");
+ assertMatches(expr.matcher("/a/b.txt/c/@something"),
"/a/b.txt/c", "/a/b.txt/c");
+ assertNotMatches(expr.matcher("/a/b.tx/c/@something"));
+
+ expr = SequencerPathExpression.compile("//*.txt[*]/c[@something] =>
.");
+ assertMatches(expr.matcher("/a/b.txt/c/@something"),
"/a/b.txt/c", "/a/b.txt/c");
+ assertNotMatches(expr.matcher("/a/b.tx/c/@something"));
+ }
+
+ @Test
public void shouldMatchExpressionsWithSegmentWildcardSelection() {
expr = SequencerPathExpression.compile("/a//c[d/e/@something] =>
.");
assertMatches(expr.matcher("/a/c/d/e/@something"), "/a/c",
"/a/c");
@@ -353,4 +368,10 @@
assertMatches(expr.matcher("/a/b/c/d/e/@something"),
"/a/b/c", "/x/b/c/z");
}
+ @Test
+ public void shouldMatchExpressionWithFilenamePatternAndChildProperty() {
+ expr =
SequencerPathExpression.compile("//(*.(jpeg|gif|bmp|pcx|png|iff|ras|pbm|pgm|ppm|psd))[*]/jcr:content[@jcr:data]=>/images/$1");
+ assertMatches(expr.matcher("/a/b/caution.png/jcr:content/@jcr:data"),
"/a/b/caution.png/jcr:content", "/images/caution.png");
+ }
+
}
Modified:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencingServiceTest.java
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencingServiceTest.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencers/SequencingServiceTest.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -39,7 +39,7 @@
import org.jboss.dna.repository.sequencers.SequencingService;
import org.jboss.dna.repository.services.ServiceAdministrator;
import org.jboss.dna.repository.util.ExecutionContext;
-import org.jboss.dna.repository.util.SimpleExecutionContext;
+import org.jboss.dna.repository.util.MockExecutionContext;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -58,7 +58,7 @@
@Before
public void beforeEach() throws Exception {
- this.executionContext = new SimpleExecutionContext(this,
REPOSITORY_WORKSPACE_NAME);
+ this.executionContext = new MockExecutionContext(this,
REPOSITORY_WORKSPACE_NAME);
this.sequencingService = new SequencingService();
this.sequencingService.setExecutionContext(this.executionContext);
this.observationService = new
ObservationService(this.executionContext.getSessionFactory());
@@ -69,6 +69,7 @@
public void afterEach() throws Exception {
super.shutdownRepository();
this.sequencingService.getAdministrator().shutdown();
+ this.observationService.getAdministrator().shutdown();
}
@Test
Copied:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/MockExecutionContext.java
(from rev 110,
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/SimpleExecutionContext.java)
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/MockExecutionContext.java
(rev 0)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/MockExecutionContext.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,67 @@
+/*
+ * 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.util;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import java.io.IOException;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import org.jboss.dna.common.SystemFailureException;
+import org.jboss.dna.common.jcr.AbstractJcrRepositoryTest;
+import org.jboss.dna.repository.util.ExecutionContext;
+import org.jboss.dna.repository.util.JcrTools;
+import org.jboss.dna.repository.util.SessionFactory;
+
+/**
+ * @author Randall Hauch
+ */
+public class MockExecutionContext implements ExecutionContext {
+
+ private JcrTools tools = new JcrTools();
+ private SessionFactory sessionFactory;
+
+ public MockExecutionContext( final AbstractJcrRepositoryTest test, final String
repositoryName ) {
+ this.sessionFactory = new SessionFactory() {
+
+ public Session createSession( String name ) throws RepositoryException {
+ assertThat(name, is(repositoryName));
+ try {
+ return test.getRepository().login(test.getTestCredentials());
+ } catch (IOException e) {
+ throw new SystemFailureException(e);
+ }
+ }
+ };
+ }
+
+ public SessionFactory getSessionFactory() {
+ return sessionFactory;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public JcrTools getTools() {
+ return tools;
+ }
+}
Property changes on:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/MockExecutionContext.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Deleted:
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/SimpleExecutionContext.java
===================================================================
---
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/SimpleExecutionContext.java 2008-04-30
19:30:18 UTC (rev 114)
+++
trunk/dna-repository/src/test/java/org/jboss/dna/repository/util/SimpleExecutionContext.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -1,67 +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.util;
-
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.assertThat;
-import java.io.IOException;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import org.jboss.dna.common.SystemFailureException;
-import org.jboss.dna.common.jcr.AbstractJcrRepositoryTest;
-import org.jboss.dna.repository.util.ExecutionContext;
-import org.jboss.dna.repository.util.JcrTools;
-import org.jboss.dna.repository.util.SessionFactory;
-
-/**
- * @author Randall Hauch
- */
-public class SimpleExecutionContext implements ExecutionContext {
-
- private JcrTools tools = new JcrTools();
- private SessionFactory sessionFactory;
-
- public SimpleExecutionContext( final AbstractJcrRepositoryTest test, final String
repositoryName ) {
- this.sessionFactory = new SessionFactory() {
-
- public Session createSession( String name ) throws RepositoryException {
- assertThat(name, is(repositoryName));
- try {
- return test.getRepository().login(test.getTestCredentials());
- } catch (IOException e) {
- throw new SystemFailureException(e);
- }
- }
- };
- }
-
- public SessionFactory getSessionFactory() {
- return sessionFactory;
- }
-
- /**
- * {@inheritDoc}
- */
- public JcrTools getTools() {
- return tools;
- }
-}
Deleted: trunk/docs/.project
===================================================================
--- trunk/docs/.project 2008-04-30 19:30:18 UTC (rev 114)
+++ trunk/docs/.project 2008-05-06 14:57:52 UTC (rev 115)
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>docs</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- </buildSpec>
- <natures>
- </natures>
-</projectDescription>
Added: trunk/docs/examples/getting_started/pom.xml
===================================================================
--- trunk/docs/examples/getting_started/pom.xml (rev 0)
+++ trunk/docs/examples/getting_started/pom.xml 2008-05-06 14:57:52 UTC (rev 115)
@@ -0,0 +1,133 @@
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss.dna.examples</groupId>
+ <artifactId>getting_started</artifactId>
+ <packaging>pom</packaging>
+ <version>0.1</version>
+ <name>Getting Started examples</name>
+ <description></description>
+
+ <modules>
+ <module>sequencers</module>
+ </modules>
+
+ <properties>
+ <dna-version>0.1-SNAPSHOT</dna-version>
+ </properties>
+
+ <dependencyManagement>
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-common</artifactId>
+ <version>${dna-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-spi</artifactId>
+ <version>${dna-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-repository</artifactId>
+ <version>${dna-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-maven-classloader</artifactId>
+ <version>${dna-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-sequencer-images</artifactId>
+ <version>${dna-version}</version>
+ </dependency>
+ <!-- Logging (require SLF4J API for compiling, but use Log4J and its SLF4J
binding for testing) -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.4.3</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <version>1.4.3</version>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.14</version>
+ </dependency>
+ <!-- Java Content Repository API -->
+ <dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ <version>1.0.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <!-- Apache Jackrabbit (JCR Implementation) -->
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-api</artifactId>
+ <version>1.3.3</version>
+ <scope>compile</scope>
+ <!-- Exclude these since they are included in JDK 1.5 -->
+ <exclusions>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-core</artifactId>
+ <version>1.3.3</version>
+ <scope>compile</scope>
+ <!-- Exclude these since they are included in JDK 1.5 -->
+ <exclusions>
+ <exclusion>
+ <groupId>xml-apis</groupId>
+ <artifactId>xml-apis</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>xerces</groupId>
+ <artifactId>xercesImpl</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <!-- Testing (note the scope) -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.4</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ <debug>true</debug>
+ <showDeprecation>true</showDeprecation>
+ <showWarnings>true</showWarnings>
+ <optimize>true</optimize>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
Property changes on: trunk/docs/examples/getting_started/sequencers
___________________________________________________________________
Name: svn:ignore
+ target
Added: trunk/docs/examples/getting_started/sequencers/.classpath
===================================================================
--- trunk/docs/examples/getting_started/sequencers/.classpath (rev
0)
+++ trunk/docs/examples/getting_started/sequencers/.classpath 2008-05-06 14:57:52 UTC (rev
115)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/main/resources"/>
+ <classpathentry kind="src" path="src/test/java"/>
+ <classpathentry kind="con"
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con"
path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+ <classpathentry kind="output" path="target/classes"/>
+</classpath>
Added: trunk/docs/examples/getting_started/sequencers/.project
===================================================================
--- trunk/docs/examples/getting_started/sequencers/.project (rev
0)
+++ trunk/docs/examples/getting_started/sequencers/.project 2008-05-06 14:57:52 UTC (rev
115)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>docs-getting-started-examples-sequencers</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.maven.ide.eclipse.maven2Builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.maven.ide.eclipse.maven2Nature</nature>
+ </natures>
+</projectDescription>
Added: trunk/docs/examples/getting_started/sequencers/pom.xml
===================================================================
--- trunk/docs/examples/getting_started/sequencers/pom.xml (rev
0)
+++ trunk/docs/examples/getting_started/sequencers/pom.xml 2008-05-06 14:57:52 UTC (rev
115)
@@ -0,0 +1,95 @@
+<project
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <parent>
+ <groupId>org.jboss.dna.examples</groupId>
+ <artifactId>getting_started</artifactId>
+ <version>0.1</version>
+ <relativePath>..</relativePath>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.jboss.dna.examples</groupId>
+ <artifactId>dna-example-sequencers</artifactId>
+ <version>0.1-SNAPSHOT</version>
+ <packaging>jar</packaging>
+ <name>Sequencer Examples</name>
+ <description>Examples that showcase how to use sequencers with a JCR
repository.</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-repository</artifactId>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-sequencer-images</artifactId>
+ <scope>runtime</scope>
+ </dependency>
+ <!--
+ Logging (require SLF4J API for compiling, but use Log4J and its SLF4J binding for
testing)
+ -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </dependency>
+ <!--
+ Java Content Repository API
+ -->
+ <dependency>
+ <groupId>javax.jcr</groupId>
+ <artifactId>jcr</artifactId>
+ </dependency>
+ <!--
+ Apache Jackrabbit (JCR Implementation) for repository implementation
+ -->
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.jackrabbit</groupId>
+ <artifactId>jackrabbit-core</artifactId>
+ </dependency>
+ <!--
+ Test cases use JUnit
+ -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <configuration>
+ <descriptors>
+ <descriptor>src/main/assembly/basic.xml</descriptor>
+ </descriptors>
+ <finalName>${pom.artifactId}</finalName>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>directory-inline</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+
+</project>
\ No newline at end of file
Added: trunk/docs/examples/getting_started/sequencers/src/main/assembly/basic.xml
===================================================================
--- trunk/docs/examples/getting_started/sequencers/src/main/assembly/basic.xml
(rev 0)
+++ trunk/docs/examples/getting_started/sequencers/src/main/assembly/basic.xml 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,57 @@
+<assembly>
+ <id>basic</id>
+ <formats>
+ <format>zip</format>
+ </formats>
+ <includeBaseDirectory>false</includeBaseDirectory>
+ <fileSets>
+ <fileSet>
+ <directory>target</directory>
+ <outputDirectory/>
+ <includes>
+ <include>*.jar</include>
+ </includes>
+ </fileSet>
+ <fileSet>
+ <directory>src/main/resources/</directory>
+ <outputDirectory/>
+ <includes>
+ <include>*.png</include>
+ <include>*.gif</include>
+ <include>*.jpg</include>
+ <include>*.pict</include>
+ </includes>
+ </fileSet>
+ </fileSets>
+ <files>
+ <file>
+ <source>src/main/config/run.sh</source>
+ <fileMode>0744</fileMode>
+ </file>
+ <file>
+ <source>src/main/resources/jackrabbitConfig.xml</source>
+ <fileMode>0644</fileMode>
+ </file>
+ <file>
+ <source>src/main/resources/jackrabbitNodeTypes.cnd</source>
+ <fileMode>0644</fileMode>
+ </file>
+ <file>
+ <source>src/main/resources/log4j.properties</source>
+ <fileMode>0644</fileMode>
+ </file>
+ </files>
+ <dependencySets>
+ <dependencySet>
+ <outputDirectory>/lib</outputDirectory>
+ <unpack>false</unpack>
+ <includes>
+ <!-- Include everything needed by the examples. -->
+ <include>*:jar:*</include>
+ </includes>
+ <!--excludes>
+ <exclude>*:sources</exclude>
+ </excludes-->
+ </dependencySet>
+ </dependencySets>
+</assembly>
\ No newline at end of file
Added: trunk/docs/examples/getting_started/sequencers/src/main/config/run.sh
===================================================================
--- trunk/docs/examples/getting_started/sequencers/src/main/config/run.sh
(rev 0)
+++ trunk/docs/examples/getting_started/sequencers/src/main/config/run.sh 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+java -Djava.ext.dirs=`pwd`/lib -cp .:dna-example-sequencers-0.1-SNAPSHOT.jar
org.jboss.example.dna.sequencers.SequencingClient $1
\ No newline at end of file
Added:
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/ConsoleInput.java
===================================================================
---
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/ConsoleInput.java
(rev 0)
+++
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/ConsoleInput.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,200 @@
+/*
+ * 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.example.dna.sequencers;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.Map;
+import org.jboss.dna.repository.sequencers.SequencingService;
+
+/**
+ * @author Randall Hauch
+ */
+public class ConsoleInput implements UserInterface {
+
+ protected static BufferedReader in = new BufferedReader(new
InputStreamReader(System.in));
+
+ public ConsoleInput( final SequencingClient client ) {
+ try {
+ System.out.println();
+ System.out.print("Starting repository and sequencing service ...
");
+ client.startRepository();
+ System.out.print("done.\nStarting sequencing service ... ");
+ client.startDnaServices();
+ System.out.println("done.");
+ System.out.println();
+
+ System.out.println(getMenu());
+ Thread eventThread = new Thread(new Runnable() {
+
+ private boolean quit = false;
+
+ public void run() {
+ try {
+ while (!quit) {
+ System.out.print(">");
+ try {
+ String input = in.readLine();
+ if (input.length() != 1) {
+ System.out.println("Please enter a valid
option.");
+ continue;
+ }
+
+ char option = input.charAt(0);
+ switch (option) {
+ case 'u':
+ client.uploadFile();
+ break;
+ case 's':
+ client.search();
+ break;
+ case 'm':
+ System.out.println(getMenu());
+ break;
+ case 'p':
+
System.out.println(getStatistics(client.getStatistics()));
+ break;
+ case 'q':
+ quit = true;
+ break;
+ default:
+ System.out.println("Invalid option.");
+ break;
+ }
+ } catch (NumberFormatException e) {
+ System.out.println("Invalid integer " +
e.getMessage());
+ } catch (IllegalArgumentException e) {
+ System.out.println(e.getMessage());
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+ } finally {
+ try {
+ // Terminate ...
+ System.out.println();
+ System.out.print("Shutting down sequencing service ...
");
+ client.shutdownDnaServices();
+ System.out.print("done.\nShutting down repository ...
");
+ client.shutdownRepository();
+ System.out.print("done.");
+ System.out.println();
+ System.out.println();
+ } catch (Exception err) {
+ System.out.println("Error shutting down sequencing
service and repository: " + err.getLocalizedMessage());
+ err.printStackTrace(System.err);
+ }
+ }
+ }
+ });
+
+ eventThread.start();
+ } catch (Exception err) {
+ System.out.println("Error: " + err.getLocalizedMessage());
+ err.printStackTrace(System.err);
+ }
+ }
+
+ protected String getMenu() {
+ StringBuilder buffer = new StringBuilder();
+ buffer.append("-----------------------------------\n");
+ buffer.append("Menu:\n");
+ buffer.append("\n");
+ buffer.append("u) Upload a file to the repository\n");
+ buffer.append("s) Search the repository using extracted metadata\n");
+ buffer.append("\n");
+ buffer.append("p) Print statistics\n");
+ buffer.append("\n");
+ buffer.append("m) Display menu\n");
+ buffer.append("q) Quit");
+ return buffer.toString();
+ }
+
+ public File getPathOfFileToUpload() throws IllegalArgumentException, IOException {
+ System.out.println("Please enter the file to upload:");
+ String path = in.readLine();
+ File file = new File(path);
+ if (!file.exists()) {
+ throw new IllegalArgumentException("The file \"" +
file.getAbsolutePath() + "\" does not exist.");
+ }
+ if (!file.canRead()) {
+ throw new IllegalArgumentException("Unable to read \"" +
file.getAbsolutePath() + "\".");
+ }
+ if (!file.isFile()) {
+ throw new IllegalArgumentException("Please specify a file. The file
\"" + file.getAbsolutePath() + "\" is a directory.");
+ }
+ return file;
+ }
+
+ public String getRepositoryPath( String defaultPath ) throws
IllegalArgumentException, IOException {
+ if (defaultPath != null) defaultPath = defaultPath.trim();
+ if (defaultPath.length() == 0) defaultPath = null;
+ String displayDefaultPath = defaultPath == null ? "" : " [" +
defaultPath.trim() + "]";
+ System.out.println("Please enter the repository path where the file should
be placed" + displayDefaultPath + ":");
+ String path = in.readLine().trim();
+ if (path.length() == 0) {
+ if (defaultPath == null) {
+ throw new IllegalArgumentException("The path \"" + path +
"\" is not valid.");
+ }
+ path = defaultPath;
+ }
+ return path;
+ }
+
+ public void displaySearchResults( List<ImageInfo> images ) {
+ System.out.println();
+ if (images.isEmpty()) {
+ System.out.println("No results were found.");
+ System.out.println();
+ return;
+ }
+ if (images.size() == 1) {
+ System.out.println("1 image was found:");
+ } else {
+ System.out.println("" + images.size() + " images were
found:");
+ }
+ int counter = 1;
+ for (ImageInfo image : images) {
+ System.out.println(" Image " + counter++);
+ System.out.println(" Name: " + image.getName());
+ System.out.println(" Path: " + image.getPath());
+ for (Map.Entry<Object, Object> entry :
image.getProperties().entrySet()) {
+ System.out.println(" " + entry.getKey() + ": " +
entry.getValue());
+ }
+ }
+ System.out.println();
+ }
+
+ public String getStatistics( SequencingService.Statistics stats ) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("\n");
+ sb.append("# nodes sequenced:
").append(stats.getNumberOfNodesSequenced()).append("\n");
+ sb.append("# nodes skipped:
").append(stats.getNumberOfNodesSkipped()).append("\n");
+ sb.append("\n");
+ return sb.toString();
+ }
+}
Added:
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/ImageInfo.java
===================================================================
---
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/ImageInfo.java
(rev 0)
+++
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/ImageInfo.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,69 @@
+/*
+ * 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.example.dna.sequencers;
+
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author Randall Hauch
+ */
+public class ImageInfo {
+
+ private final Properties properties = new Properties();
+ private final String name;
+ private final String path;
+
+ protected ImageInfo( String path, String name, Properties props ) {
+ this.name = name;
+ this.path = path;
+ if (props != null) this.properties.putAll(props);
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getPath() {
+ return this.path;
+ }
+
+ public Properties getProperties() {
+ return this.properties;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (Map.Entry<Object, Object> entry : this.properties.entrySet()) {
+
sb.append(entry.getKey()).append("=>").append(entry.getValue());
+ if (first) {
+ first = false;
+ } else {
+ sb.append(", ");
+ }
+ }
+ return this.name + " (at " + this.path + ") with properties
{" + sb.toString() + "}";
+ }
+
+}
Added:
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java
===================================================================
---
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java
(rev 0)
+++
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/SequencingClient.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,352 @@
+/*
+ * 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.example.dna.sequencers;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.TimeUnit;
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
+import javax.jcr.observation.Event;
+import net.jcip.annotations.NotThreadSafe;
+import org.apache.jackrabbit.api.JackrabbitNodeTypeManager;
+import org.apache.jackrabbit.core.TransientRepository;
+import org.jboss.dna.common.SystemFailureException;
+import org.jboss.dna.repository.observation.ObservationService;
+import org.jboss.dna.repository.sequencers.SequencerConfig;
+import org.jboss.dna.repository.sequencers.SequencingService;
+import org.jboss.dna.repository.util.ExecutionContext;
+import org.jboss.dna.repository.util.JcrTools;
+import org.jboss.dna.repository.util.SimpleExecutionContext;
+
+/**
+ * @author Randall Hauch
+ */
+@NotThreadSafe
+public class SequencingClient {
+
+ public static final String DEFAULT_JACKRABBIT_CONFIG_PATH =
"jackrabbitConfig.xml";
+ public static final String DEFAULT_WORKING_DIRECTORY = "repositoryData";
+ public static final String DEFAULT_REPOSITORY_NAME = "repo";
+ public static final String DEFAULT_WORKSPACE_NAME = "default";
+ public static final String DEFAULT_USERNAME = "jsmith";
+ public static final char[] DEFAULT_PASSWORD = "secret".toCharArray();
+
+ public static void main( String[] args ) throws Exception {
+ SequencingClient client = new SequencingClient();
+ client.setRepositoryInformation(DEFAULT_REPOSITORY_NAME, DEFAULT_WORKSPACE_NAME,
"jsmith", "secret".toCharArray());
+ client.setUserInterface(new ConsoleInput(client));
+ }
+
+ private String repositoryName;
+ private String workspaceName;
+ private String username;
+ private char[] password;
+ private String jackrabbitConfigPath;
+ private String workingDirectory;
+ private Session keepAliveSession;
+ private Repository repository;
+ private SequencingService sequencingService;
+ private ObservationService observationService;
+ private UserInterface userInterface;
+ private ExecutionContext executionContext;
+
+ public SequencingClient() {
+ setJackrabbitConfigPath(DEFAULT_JACKRABBIT_CONFIG_PATH);
+ setWorkingDirectory(DEFAULT_WORKING_DIRECTORY);
+ setRepositoryInformation(DEFAULT_REPOSITORY_NAME, DEFAULT_WORKSPACE_NAME,
DEFAULT_USERNAME, DEFAULT_PASSWORD);
+ }
+
+ public void setUserInterface( UserInterface userInterface ) {
+ this.userInterface = userInterface;
+ }
+
+ protected void setWorkingDirectory( String workingDirectoryPath ) {
+ this.workingDirectory = workingDirectoryPath != null ? workingDirectoryPath :
DEFAULT_WORKING_DIRECTORY;
+ }
+
+ protected void setJackrabbitConfigPath( String jackrabbitConfigPath ) {
+ this.jackrabbitConfigPath = jackrabbitConfigPath != null ? jackrabbitConfigPath :
DEFAULT_JACKRABBIT_CONFIG_PATH;
+ }
+
+ protected void setRepositoryInformation( String repositoryName, String workspaceName,
String username, char[] password ) {
+ if (this.repository != null) {
+ throw new IllegalArgumentException("Unable to set repository information
when repository is already running");
+ }
+ this.repositoryName = repositoryName != null ? repositoryName :
DEFAULT_REPOSITORY_NAME;
+ this.workspaceName = workspaceName != null ? workspaceName :
DEFAULT_WORKSPACE_NAME;
+ this.username = username;
+ this.password = password;
+ }
+
+ public void startRepository() throws Exception {
+ if (this.repository == null) {
+ try {
+
+ // Load the Jackrabbit configuration ...
+ File configFile = new File(this.jackrabbitConfigPath);
+ if (!configFile.exists()) {
+ throw new SystemFailureException("The Jackrabbit configuration
file cannot be found at " + configFile.getAbsoluteFile());
+ }
+ if (!configFile.canRead()) {
+ throw new SystemFailureException("Unable to read the Jackrabbit
configuration file at " + configFile.getAbsoluteFile());
+ }
+ String pathToConfig = configFile.getAbsolutePath();
+
+ // Find the directory where the Jackrabbit repository data will be stored
...
+ File workingDirectory = new File(this.workingDirectory);
+ if (workingDirectory.exists()) {
+ if (!workingDirectory.isDirectory()) {
+ throw new SystemFailureException("Unable to create working
directory at " + workingDirectory.getAbsolutePath());
+ }
+ }
+ String workingDirectoryPath = workingDirectory.getAbsolutePath();
+
+ // Get the Jackrabbit custom node definition (CND) file ...
+ URL cndFile =
Thread.currentThread().getContextClassLoader().getResource("jackrabbitNodeTypes.cnd");
+
+ // Create the Jackrabbit repository instance and establish a session to
keep the repository alive ...
+ this.repository = new TransientRepository(pathToConfig,
workingDirectoryPath);
+ if (this.username != null) {
+ Credentials credentials = new SimpleCredentials(this.username,
this.password);
+ this.keepAliveSession = this.repository.login(credentials,
this.workspaceName);
+ } else {
+ this.keepAliveSession = this.repository.login();
+ }
+
+ try {
+ // Register the node types (only valid the first time) ...
+ JackrabbitNodeTypeManager mgr =
(JackrabbitNodeTypeManager)this.keepAliveSession.getWorkspace().getNodeTypeManager();
+ mgr.registerNodeTypes(cndFile.openStream(),
JackrabbitNodeTypeManager.TEXT_X_JCR_CND);
+ } catch (RepositoryException e) {
+ if (!e.getMessage().contains("already exists")) throw e;
+ }
+
+ } catch (Exception e) {
+ this.repository = null;
+ this.keepAliveSession = null;
+ throw e;
+ }
+ }
+ }
+
+ public void shutdownRepository() throws Exception {
+ if (this.repository != null) {
+ try {
+ this.keepAliveSession.logout();
+ } finally {
+ this.repository = null;
+ this.keepAliveSession = null;
+ }
+ }
+ }
+
+ public void startDnaServices() throws Exception {
+ if (this.repository == null) {
+ this.startRepository();
+ }
+ if (this.sequencingService != null) {
+ return;
+ }
+ // Create an execution context for the sequencing service.
+ // The repository instances and workspace names are registered, and that the
service will reference.
+ // the repository ...
+ SimpleExecutionContext executionContext = new SimpleExecutionContext();
+ // Register the JCR repository ...
+ executionContext.registerRepository(this.repositoryName, this.repository);
+ if (this.username != null) {
+ Credentials credentials = new SimpleCredentials(this.username,
this.password);
+ executionContext.registerCredentials(this.repositoryName + "/" +
this.workspaceName, credentials);
+ }
+ this.executionContext = executionContext;
+
+ // Create the sequencing service ...
+ this.sequencingService = new SequencingService();
+ this.sequencingService.setExecutionContext(executionContext);
+
+ // Add the configuration for the image sequencer. This sequencer class should be
on the thread's current context class
+ // loader, or if that's null the classloader that loaded the
SequencingService class.
+ //
+ // The path expressions tell the service that this sequencer should be invoked on
the "jcr:data" property
+ // on the "jcr:content" child node of any node uploaded to the
repository whose name ends with one of the
+ // supported extensions, and it should place the output metadata in a node with
the same name as the file
+ // but immediately below the "/images" node. Path expressions can be
fairly complex, and can even
+ // specify that the generated information be placed in a different repository.
+ //
+ // Sequencers can be added before or after the service is started.
+ String name = "Image Sequencer";
+ String desc = "Sequences image files to extract the characteristics of the
image";
+ String classname =
"org.jboss.dna.sequencer.images.ImageMetadataSequencer";
+ String[] classpath = null; // Use the current classpath
+ String[] pathExpressions =
{"//(*.(jpeg|gif|bmp|pcx|png|iff|ras|pbm|pgm|ppm|psd))[*]/jcr:content[@jcr:data]
=> /images/$1"};
+ SequencerConfig imageSequencerConfig = new SequencerConfig(name, desc, classname,
classpath, pathExpressions);
+ this.sequencingService.addSequencer(imageSequencerConfig);
+
+ // Start up the sequencing service ...
+ this.sequencingService.getAdministrator().start();
+
+ // Register the sequencing service as a listener using the observation service
...
+ this.observationService = new
ObservationService(this.executionContext.getSessionFactory());
+ this.observationService.getAdministrator().start();
+ this.observationService.addListener(this.sequencingService);
+ this.observationService.monitor(this.repositoryName + "/" +
this.workspaceName, Event.NODE_ADDED | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED);
+ }
+
+ public void shutdownDnaServices() throws Exception {
+ if (this.sequencingService == null) return;
+
+ try {
+ // Shut down the service and wait until it's all shut down ...
+ this.sequencingService.getAdministrator().shutdown();
+ this.sequencingService.getAdministrator().awaitTermination(5,
TimeUnit.SECONDS);
+
+ // Shut down the observation service ...
+ this.observationService.getAdministrator().shutdown();
+ this.observationService.getAdministrator().awaitTermination(5,
TimeUnit.SECONDS);
+
+ } finally {
+ this.sequencingService = null;
+ this.observationService = null;
+ }
+ }
+
+ public SequencingService.Statistics getStatistics() {
+ return this.sequencingService.getStatistics();
+ }
+
+ public void uploadFile() throws Exception {
+ File file = this.userInterface.getPathOfFileToUpload();
+ String nodePath = this.userInterface.getRepositoryPath("/a/b/" +
file.getName());
+ String mimeType = getMimeType(file);
+ uploadFile(new FileInputStream(file), nodePath, mimeType);
+ }
+
+ public void search() throws Exception {
+ List<ImageInfo> images = getImages();
+ // Display the search results ...
+ this.userInterface.displaySearchResults(images);
+ }
+
+ protected List<ImageInfo> getImages() throws Exception {
+ List<ImageInfo> images = new ArrayList<ImageInfo>();
+ Session session = createSession();
+ try {
+ // Find the image node ...
+ Node root = session.getRootNode();
+ if (root.hasNode("images")) {
+ Node imagesNode = root.getNode("images");
+
+ // Iterate over each child ...
+ for (NodeIterator iter = imagesNode.getNodes(); iter.hasNext();) {
+ Node imageNode = iter.nextNode();
+ String nodePath = imageNode.getPath();
+ String nodeName = imageNode.getName();
+ if (imageNode.hasNode("image:metadata")) {
+ imageNode = imageNode.getNode("image:metadata");
+
+ // Create a Properties object containing the properties for this
node; ignore any children ...
+ Properties props = new Properties();
+ for (PropertyIterator propertyIter = imageNode.getProperties();
propertyIter.hasNext();) {
+ Property property = propertyIter.nextProperty();
+ String name = property.getName();
+ String stringValue = null;
+ if (property.getDefinition().isMultiple()) {
+ StringBuilder sb = new StringBuilder();
+ boolean first = true;
+ for (Value value : property.getValues()) {
+ if (!first) {
+ sb.append(", ");
+ first = false;
+ }
+ sb.append(value.getString());
+ }
+ stringValue = sb.toString();
+ } else {
+ stringValue = property.getValue().getString();
+ }
+ props.put(name, stringValue);
+ }
+ // Create the image information object, and add it to the
collection ...
+ ImageInfo info = new ImageInfo(nodePath, nodeName, props);
+ images.add(info);
+ }
+ }
+ }
+ } finally {
+ session.logout();
+ }
+ return images;
+ }
+
+ protected Session createSession() throws RepositoryException {
+ return
this.executionContext.getSessionFactory().createSession(this.repositoryName +
"/" + this.workspaceName);
+ }
+
+ protected boolean uploadFile( InputStream content, String nodePath, String mimeType )
throws Exception {
+ Session session = createSession();
+ JcrTools tools = this.executionContext.getTools();
+ try {
+ // Create the node at the supplied path ...
+ Node node = tools.findOrCreateNode(session, nodePath, "nt:folder",
"nt:file");
+
+ // Upload the file to that node ...
+ Node contentNode = tools.findOrCreateChild(session, node,
"jcr:content", "nt:resource");
+ contentNode.setProperty("jcr:mimeType", mimeType);
+ contentNode.setProperty("jcr:lastModified",
Calendar.getInstance());
+ contentNode.setProperty("jcr:data", content);
+
+ // Save the session ...
+ session.save();
+ } finally {
+ session.logout();
+ }
+ return true;
+ }
+
+ protected String getMimeType( File file ) {
+ String extension = file.getName().toLowerCase();
+ if (extension.endsWith(".gif")) return "image/gif";
+ if (extension.endsWith(".png")) return "image/png";
+ if (extension.endsWith(".pict")) return "image/x-pict";
+ if (extension.endsWith(".bmp")) return "image/bmp";
+ if (extension.endsWith(".jpg")) return "image/jpeg";
+ if (extension.endsWith(".jpe")) return "image/jpeg";
+ if (extension.endsWith(".jpeg")) return "image/jpeg";
+ if (extension.endsWith(".ras")) return "image/x-cmu-raster";
+ throw new SystemFailureException("Unknown mime type for file " +
file);
+ }
+
+}
Added:
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/UserInterface.java
===================================================================
---
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/UserInterface.java
(rev 0)
+++
trunk/docs/examples/getting_started/sequencers/src/main/java/org/jboss/example/dna/sequencers/UserInterface.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,38 @@
+/*
+ * 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.example.dna.sequencers;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * @author Randall Hauch
+ */
+public interface UserInterface {
+
+ public File getPathOfFileToUpload() throws IllegalArgumentException, IOException;
+
+ public String getRepositoryPath( String defaultPath ) throws
IllegalArgumentException, IOException;
+
+ public void displaySearchResults( List<ImageInfo> images ) throws IOException;
+}
Added: trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.gif
===================================================================
(Binary files differ)
Property changes on:
trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.jpg
===================================================================
(Binary files differ)
Property changes on:
trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.jpg
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.pict
===================================================================
(Binary files differ)
Property changes on:
trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.pict
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.png
===================================================================
(Binary files differ)
Property changes on:
trunk/docs/examples/getting_started/sequencers/src/main/resources/caution.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added:
trunk/docs/examples/getting_started/sequencers/src/main/resources/jackrabbitConfig.xml
===================================================================
---
trunk/docs/examples/getting_started/sequencers/src/main/resources/jackrabbitConfig.xml
(rev 0)
+++
trunk/docs/examples/getting_started/sequencers/src/main/resources/jackrabbitConfig.xml 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,115 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+
http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE Repository PUBLIC "-//The Apache Software Foundation//DTD Jackrabbit
1.2//EN"
+
"http://jackrabbit.apache.org/dtd/repository-1.2.dtd">
+<!-- Example Repository Configuration File -->
+<Repository>
+ <!--
+ virtual file system where the repository stores global state
+ (e.g. registered namespaces, custom node types, etc.)
+ -->
+ <FileSystem
class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${rep.home}/repository"/>
+ </FileSystem>
+
+ <!--
+ security configuration
+ -->
+ <Security appName="Jackrabbit">
+ <!--
+ access manager:
+ class: FQN of class implementing the AccessManager interface
+ -->
+ <AccessManager
class="org.apache.jackrabbit.core.security.SimpleAccessManager">
+ <!-- <param name="config"
value="${rep.home}/access.xml"/> -->
+ </AccessManager>
+
+ <LoginModule
class="org.apache.jackrabbit.core.security.SimpleLoginModule">
+ <!-- anonymous user name ('anonymous' is the default value) -->
+ <param name="anonymousId" value="anonymous"/>
+ <!--
+ default user name to be used instead of the anonymous user
+ when no login credentials are provided (unset by default)
+ -->
+ <!-- <param name="defaultUserId"
value="superuser"/> -->
+ </LoginModule>
+ </Security>
+
+ <!--
+ location of workspaces root directory and name of default workspace
+ -->
+ <Workspaces rootPath="${rep.home}/workspaces"
defaultWorkspace="default"/>
+ <!--
+ workspace configuration template:
+ used to create the initial workspace if there's no workspace yet
+ -->
+ <Workspace name="Jackrabbit Core">
+ <!--
+ virtual file system of the workspace:
+ class: FQN of class implementing the FileSystem interface
+ -->
+ <FileSystem
class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${wsp.home}"/>
+ </FileSystem>
+ <!--
+ persistence manager of the workspace:
+ class: FQN of class implementing the PersistenceManager interface
+ -->
+ <PersistenceManager
class="org.apache.jackrabbit.core.persistence.mem.InMemPersistenceManager">
+ <param name="persistent" value="false"/>
+ </PersistenceManager>
+ <!--
+ Search index and the file system it uses.
+ class: FQN of class implementing the QueryHandler interface
+ -->
+ <SearchIndex
class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path" value="${wsp.home}/index"/>
+ </SearchIndex>
+ </Workspace>
+
+ <!--
+ Configures the versioning
+ -->
+ <Versioning rootPath="${rep.home}/version">
+ <!--
+ Configures the filesystem to use for versioning for the respective
+ persistence manager
+ -->
+ <FileSystem
class="org.apache.jackrabbit.core.fs.local.LocalFileSystem">
+ <param name="path" value="${rep.home}/version" />
+ </FileSystem>
+
+ <!--
+ Configures the persistence manager to be used for persisting version state.
+ Please note that the current versioning implementation is based on
+ a 'normal' persistence manager, but this could change in future
+ implementations.
+ -->
+ <PersistenceManager
class="org.apache.jackrabbit.core.persistence.mem.InMemPersistenceManager">
+ <param name="persistent" value="false"/>
+ </PersistenceManager>
+ </Versioning>
+
+ <!--
+ Search index for content that is shared repository wide
+ (/jcr:system tree, contains mainly versions)
+ -->
+ <SearchIndex
class="org.apache.jackrabbit.core.query.lucene.SearchIndex">
+ <param name="path"
value="${rep.home}/repository/index"/>
+ </SearchIndex>
+</Repository>
Added:
trunk/docs/examples/getting_started/sequencers/src/main/resources/jackrabbitNodeTypes.cnd
===================================================================
---
trunk/docs/examples/getting_started/sequencers/src/main/resources/jackrabbitNodeTypes.cnd
(rev 0)
+++
trunk/docs/examples/getting_started/sequencers/src/main/resources/jackrabbitNodeTypes.cnd 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,37 @@
+<jcr='http://www.jcp.org/jcr/1.0'>
+<nt='http://www.jcp.org/jcr/nt/1.0'>
+<mix='http://www.jcp.org/jcr/mix/1.0'>
+<image='http://jboss.org/dna/images/1.0'>
+
+// ----------------------------------------------------------
+// JCR Pre-defined Mixin Types that are not loaded by default
+// ----------------------------------------------------------
+
+[mix:mimeType] mixin
+ - jcr:mimeType (string)
+ - jcr:encoding (string)
+
+
+// -------------------
+// DNA Image Sequencer
+// -------------------
+
+/**
+ * Marker mixin that defines the root of a Maven 2 repository.
+ */
+[image:metadata] > nt:unstructured
+ - image:mimeType (string)
+ - image:encoding (string)
+ - image:formatName (string) mandatory
+ - image:width (long)
+ - image:height (long)
+ - image:bitsPerPixel (long)
+ - image:progressive (boolean)
+ - image:numberOfImages (long)
+ - image:physicalWidthDpi (long)
+ - image:physicalHeightDpi (long)
+ - image:physicalWidthInches (long)
+ - image:physicalHeightInches (long)
+
+
+
Added: trunk/docs/examples/getting_started/sequencers/src/main/resources/log4j.properties
===================================================================
--- trunk/docs/examples/getting_started/sequencers/src/main/resources/log4j.properties
(rev 0)
+++
trunk/docs/examples/getting_started/sequencers/src/main/resources/log4j.properties 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,17 @@
+# Direct log messages to stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.Target=System.out
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %m%n
+
+# Root logger option
+log4j.rootLogger=INFO, stdout
+
+# Set up the default logging to be INFO level, then override specific units
+log4j.logger.org.jboss.dna=INFO
+log4j.logger.org.jboss.dna.tests.integration.jackrabbit.JackrabbitMySqlStressTest=DEBUG
+
+# Jackrabbit logging
+log4j.logger.org.apache.jackrabbit=WARN, stdout
+log4j.logger.org.apache.derby=INFO, stdout
+
Added:
trunk/docs/examples/getting_started/sequencers/src/test/java/org/jboss/example/dna/sequencers/SequencingClientTest.java
===================================================================
---
trunk/docs/examples/getting_started/sequencers/src/test/java/org/jboss/example/dna/sequencers/SequencingClientTest.java
(rev 0)
+++
trunk/docs/examples/getting_started/sequencers/src/test/java/org/jboss/example/dna/sequencers/SequencingClientTest.java 2008-05-06
14:57:52 UTC (rev 115)
@@ -0,0 +1,89 @@
+/*
+ * 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.example.dna.sequencers;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+import java.net.URL;
+import java.util.List;
+import org.jboss.dna.common.util.FileUtil;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author Randall Hauch
+ */
+public class SequencingClientTest {
+
+ private URL file;
+ private SequencingClient client;
+
+ @Before
+ public void beforeEach() throws Exception {
+ this.file =
Thread.currentThread().getContextClassLoader().getResource("caution.png");
+ client = new SequencingClient();
+ client.setWorkingDirectory("target/repositoryData");
+
client.setJackrabbitConfigPath("src/main/resources/jackrabbitConfig.xml");
+ FileUtil.delete("target/repositoryData");
+ }
+
+ @After
+ public void afterEach() throws Exception {
+ client.shutdownDnaServices();
+ client.shutdownRepository();
+ FileUtil.delete("target/repositoryData");
+ }
+
+ @Test
+ public void shouldStartupAndShutdownRepository() throws Exception {
+ client.startRepository();
+ client.shutdownRepository();
+
+ }
+
+ @Test
+ public void shouldStartupAndShutdownRepositoryAndSequencingService() throws Exception
{
+ client.startRepository();
+ client.startDnaServices();
+ client.shutdownDnaServices();
+ client.shutdownRepository();
+ }
+
+ @Test
+ public void shouldUploadFile() throws Exception {
+ client.startRepository();
+ client.startDnaServices();
+ client.uploadFile(file.openStream(), "/a/b/caution.png",
"image/png");
+
+ // Let the sequencing start ...
+ Thread.sleep(1000);
+ client.shutdownDnaServices(); // this will block untill all processing has been
done ...
+
+ List<ImageInfo> images = client.getImages();
+ assertThat(images.size(), is(1));
+ for (ImageInfo image : images) {
+ System.out.println("Image: " + image);
+ }
+ }
+
+}
Added: trunk/docs/getting_started/.project
===================================================================
--- trunk/docs/getting_started/.project (rev 0)
+++ trunk/docs/getting_started/.project 2008-05-06 14:57:52 UTC (rev 115)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>docs-getting-started</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ </buildSpec>
+ <natures>
+ </natures>
+</projectDescription>
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2008-04-30 19:30:18 UTC (rev 114)
+++ trunk/pom.xml 2008-05-06 14:57:52 UTC (rev 115)
@@ -33,6 +33,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
+ <version>2.0.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>