DNA SVN: r1197 - branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-09-09 17:27:02 -0400 (Wed, 09 Sep 2009)
New Revision: 1197
Modified:
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/NewServerAction.java
Log:
Changed super class to Action as this action does not care about selection.
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/NewServerAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/NewServerAction.java 2009-09-09 21:25:07 UTC (rev 1196)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/NewServerAction.java 2009-09-09 21:27:02 UTC (rev 1197)
@@ -25,9 +25,9 @@
import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.DNA_IMAGE_16x;
import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.NEW_SERVER_IMAGE;
+import org.eclipse.jface.action.Action;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.actions.BaseSelectionListenerAction;
import org.jboss.dna.web.jcr.rest.client.ServerManager;
import org.jboss.dna.web.jcr.rest.client.domain.Server;
import org.jboss.dna.web.jcr.rest.client.swt.Activator;
@@ -39,7 +39,7 @@
*
* @since 0.6
*/
-public final class NewServerAction extends BaseSelectionListenerAction {
+public final class NewServerAction extends Action {
// ===========================================================================================================================
// Fields
14 years, 8 months
DNA SVN: r1196 - branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-09-09 17:25:07 -0400 (Wed, 09 Sep 2009)
New Revision: 1196
Modified:
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/DeleteServerDialog.java
Log:
Added null check on constructor arg.
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/DeleteServerDialog.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/DeleteServerDialog.java 2009-09-09 19:30:42 UTC (rev 1195)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/DeleteServerDialog.java 2009-09-09 21:25:07 UTC (rev 1196)
@@ -34,6 +34,7 @@
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
+import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.web.jcr.rest.client.domain.IDnaObject;
import org.jboss.dna.web.jcr.rest.client.domain.Server;
import org.jboss.dna.web.jcr.rest.client.swt.Activator;
@@ -71,6 +72,8 @@
Collection<Server> serversBeingDeleted ) {
super(parentShell, RestClientI18n.deleteServerDialogTitle.text(), Activator.getDefault().getImage(DNA_IMAGE_16x), null,
MessageDialog.QUESTION, new String[] {IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL}, 0);
+
+ CheckArg.isNotNull(serversBeingDeleted, "serversBeingDeleted"); //$NON-NLS-1$
this.serversBeingDeleted = serversBeingDeleted;
// make sure dialog is resizable
14 years, 8 months
DNA SVN: r1195 - in trunk/dna-common/src: test/java/org/jboss/dna/common/text and 1 other directory.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-09-09 15:30:42 -0400 (Wed, 09 Sep 2009)
New Revision: 1195
Modified:
trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java
trunk/dna-common/src/test/java/org/jboss/dna/common/text/TokenStreamTest.java
Log:
Added more convenience methods on TokenStream parser framework.
Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java 2009-09-04 20:57:55 UTC (rev 1194)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java 2009-09-09 19:30:42 UTC (rev 1195)
@@ -537,6 +537,40 @@
}
/**
+ * Attempt to consume this current token as the next tokens as long as they match the expected values, or throw an exception
+ * if the token does not match.
+ * <p>
+ * The {@link #ANY_VALUE ANY_VALUE} constant can be used in the expected values as a wildcard.
+ * </p>
+ *
+ * @param nextTokens the expected values for the next tokens
+ * @throws ParsingException if the current token doesn't match the supplied value
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public void consume( String[] nextTokens ) throws ParsingException, IllegalStateException {
+ for (String nextExpected : nextTokens) {
+ consume(nextExpected);
+ }
+ }
+
+ /**
+ * Attempt to consume this current token as the next tokens as long as they match the expected values, or throw an exception
+ * if the token does not match.
+ * <p>
+ * The {@link #ANY_VALUE ANY_VALUE} constant can be used in the expected values as a wildcard.
+ * </p>
+ *
+ * @param nextTokens the expected values for the next tokens
+ * @throws ParsingException if the current token doesn't match the supplied value
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public void consume( Iterable<String> nextTokens ) throws ParsingException, IllegalStateException {
+ for (String nextExpected : nextTokens) {
+ consume(nextExpected);
+ }
+ }
+
+ /**
* Attempt to consume this current token if it matches the expected value, and return whether this method was indeed able to
* consume the token.
* <p>
@@ -632,6 +666,86 @@
}
/**
+ * Attempt to consume this current token and the next tokens if and only if they match the expected values, and return whether
+ * this method was indeed able to consume all of the supplied tokens.
+ * <p>
+ * This is <i>not</i> the same as calling {@link #canConsume(String)} for each of the supplied arguments, since this method
+ * ensures that <i>all</i> of the supplied values can be consumed.
+ * </p>
+ * <p>
+ * This method <i>is</i> equivalent to calling the following:
+ *
+ * <pre>
+ *
+ * if ( tokens.matches(currentExpected,expectedForNextTokens) ) { tokens.consume(currentExpected,expectedForNextTokens); }
+ *
+ * </pre>
+ * </p>
+ * <p>
+ * The {@link #ANY_VALUE ANY_VALUE} constant can be used in the expected values as a wildcard.
+ * </p>
+ *
+ * @param nextTokens the expected values of the next tokens
+ * @return true if the current token did match and was consumed, or false if the current token did not match and therefore was
+ * not consumed
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public boolean canConsume( String[] nextTokens ) throws IllegalStateException {
+ if (completed) return false;
+ ListIterator<Token> iter = tokens.listIterator(tokenIterator.previousIndex());
+ Token token = null;
+ for (String nextExpected : nextTokens) {
+ if (!iter.hasNext()) return false;
+ token = iter.next();
+ if (nextExpected == ANY_VALUE) continue;
+ if (!token.matches(nextExpected)) return false;
+ }
+ this.tokenIterator = iter;
+ this.currentToken = tokenIterator.hasNext() ? tokenIterator.next() : null;
+ return true;
+ }
+
+ /**
+ * Attempt to consume this current token and the next tokens if and only if they match the expected values, and return whether
+ * this method was indeed able to consume all of the supplied tokens.
+ * <p>
+ * This is <i>not</i> the same as calling {@link #canConsume(String)} for each of the supplied arguments, since this method
+ * ensures that <i>all</i> of the supplied values can be consumed.
+ * </p>
+ * <p>
+ * This method <i>is</i> equivalent to calling the following:
+ *
+ * <pre>
+ *
+ * if ( tokens.matches(currentExpected,expectedForNextTokens) ) { tokens.consume(currentExpected,expectedForNextTokens); }
+ *
+ * </pre>
+ * </p>
+ * <p>
+ * The {@link #ANY_VALUE ANY_VALUE} constant can be used in the expected values as a wildcard.
+ * </p>
+ *
+ * @param nextTokens the expected values of the next tokens
+ * @return true if the current token did match and was consumed, or false if the current token did not match and therefore was
+ * not consumed
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public boolean canConsume( Iterable<String> nextTokens ) throws IllegalStateException {
+ if (completed) return false;
+ ListIterator<Token> iter = tokens.listIterator(tokenIterator.previousIndex());
+ Token token = null;
+ for (String nextExpected : nextTokens) {
+ if (!iter.hasNext()) return false;
+ token = iter.next();
+ if (nextExpected == ANY_VALUE) continue;
+ if (!token.matches(nextExpected)) return false;
+ }
+ this.tokenIterator = iter;
+ this.currentToken = tokenIterator.hasNext() ? tokenIterator.next() : null;
+ return true;
+ }
+
+ /**
* Determine if the current token matches the expected value.
* <p>
* The {@link #ANY_VALUE ANY_VALUE} constant can be used as a wildcard.
@@ -695,6 +809,52 @@
}
/**
+ * Determine if the next few tokens match the expected values.
+ * <p>
+ * The {@link #ANY_VALUE ANY_VALUE} constant can be used in the expected values as a wildcard.
+ * </p>
+ *
+ * @param nextTokens the expected value of the next tokens
+ * @return true if the tokens did match, or false otherwise
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public boolean matches( String[] nextTokens ) throws IllegalStateException {
+ if (completed) return false;
+ ListIterator<Token> iter = tokens.listIterator(tokenIterator.previousIndex());
+ Token token = null;
+ for (String nextExpected : nextTokens) {
+ if (!iter.hasNext()) return false;
+ token = iter.next();
+ if (nextExpected == ANY_VALUE) continue;
+ if (!token.matches(nextExpected)) return false;
+ }
+ return true;
+ }
+
+ /**
+ * Determine if the next few tokens match the expected values.
+ * <p>
+ * The {@link #ANY_VALUE ANY_VALUE} constant can be used in the expected values as a wildcard.
+ * </p>
+ *
+ * @param nextTokens the expected value of the next tokens
+ * @return true if the tokens did match, or false otherwise
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public boolean matches( Iterable<String> nextTokens ) throws IllegalStateException {
+ if (completed) return false;
+ ListIterator<Token> iter = tokens.listIterator(tokenIterator.previousIndex());
+ Token token = null;
+ for (String nextExpected : nextTokens) {
+ if (!iter.hasNext()) return false;
+ token = iter.next();
+ if (nextExpected == ANY_VALUE) continue;
+ if (!token.matches(nextExpected)) return false;
+ }
+ return true;
+ }
+
+ /**
* Determine if the next few tokens have the supplied types.
* <p>
* The {@link #ANY_TYPE ANY_TYPE} constant can be used in the expected values as a wildcard.
@@ -722,6 +882,29 @@
}
/**
+ * Determine if the next few tokens have the supplied types.
+ * <p>
+ * The {@link #ANY_TYPE ANY_TYPE} constant can be used in the expected values as a wildcard.
+ * </p>
+ *
+ * @param typesForNextTokens the expected type for each of the next tokens
+ * @return true if the tokens did match, or false otherwise
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public boolean matches( int[] typesForNextTokens ) throws IllegalStateException {
+ if (completed) return false;
+ ListIterator<Token> iter = tokens.listIterator(tokenIterator.previousIndex());
+ Token token = null;
+ for (int nextExpectedType : typesForNextTokens) {
+ if (!iter.hasNext()) return false;
+ token = iter.next();
+ if (nextExpectedType == ANY_TYPE) continue;
+ if (token.type() != nextExpectedType) return false;
+ }
+ return true;
+ }
+
+ /**
* Determine if the next token matches one of the supplied values.
*
* @param firstOption the first option for the value of the current token
@@ -741,6 +924,38 @@
}
/**
+ * Determine if the next token matches one of the supplied values.
+ *
+ * @param options the options for the value of the current token
+ * @return true if the current token's value did match one of the suplied options, or false otherwise
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public boolean matchesAnyOf( String[] options ) throws IllegalStateException {
+ if (completed) return false;
+ Token current = currentToken();
+ for (String option : options) {
+ if (current.matches(option)) return true;
+ }
+ return false;
+ }
+
+ /**
+ * Determine if the next token matches one of the supplied values.
+ *
+ * @param options the options for the value of the current token
+ * @return true if the current token's value did match one of the suplied options, or false otherwise
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public boolean matchesAnyOf( Iterable<String> options ) throws IllegalStateException {
+ if (completed) return false;
+ Token current = currentToken();
+ for (String option : options) {
+ if (current.matches(option)) return true;
+ }
+ return false;
+ }
+
+ /**
* Determine if the next token have one of the supplied types.
*
* @param firstTypeOption the first option for the type of the current token
@@ -760,6 +975,22 @@
}
/**
+ * Determine if the next token have one of the supplied types.
+ *
+ * @param typeOptions the options for the type of the current token
+ * @return true if the current token's type matched one of the supplied options, or false otherwise
+ * @throws IllegalStateException if this method was called before the stream was {@link #start() started}
+ */
+ public boolean matchesAnyOf( int[] typeOptions ) throws IllegalStateException {
+ if (completed) return false;
+ int currentType = currentToken().type();
+ for (int nextTypeOption : typeOptions) {
+ if (currentType == nextTypeOption) return true;
+ }
+ return false;
+ }
+
+ /**
* Determine if this stream has another token beyond the current position.
*
* @return true if there is another token, or false otherwise
Modified: trunk/dna-common/src/test/java/org/jboss/dna/common/text/TokenStreamTest.java
===================================================================
--- trunk/dna-common/src/test/java/org/jboss/dna/common/text/TokenStreamTest.java 2009-09-04 20:57:55 UTC (rev 1194)
+++ trunk/dna-common/src/test/java/org/jboss/dna/common/text/TokenStreamTest.java 2009-09-09 19:30:42 UTC (rev 1195)
@@ -292,6 +292,14 @@
}
@Test
+ public void shouldReturnTrueFromCanConsumeArrayOfTokensIfTheyAllMatch() {
+ makeCaseInsensitive();
+ assertThat(tokens.matches(new String[] {"SELECT", "ALL", "COLUMNS", "FROM", "THIS", "TABLE"}), is(true));
+ assertThat(tokens.canConsume(new String[] {"SELECT", "ALL", "COLUMNS", "FROM", "THIS", "TABLE"}), is(true));
+ assertThat(tokens.hasNext(), is(false));
+ }
+
+ @Test
public void shouldReturnTrueFromCanConsumeMultipleTokensIfTheyDoNotAllMatch() {
makeCaseInsensitive();
// Unable to consume unless they all match ...
14 years, 8 months
DNA SVN: r1194 - in branches/eclipse/org.jboss.dna.publish.ui.swt: src/org/jboss/dna/web/jcr/rest/client/swt and 3 other directories.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-09-04 16:57:55 -0400 (Fri, 04 Sep 2009)
New Revision: 1194
Added:
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/DnaPreferencePage.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/ExtensionEditor.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/NewFileExtensionDialog.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/PrefUtils.java
Modified:
branches/eclipse/org.jboss.dna.publish.ui.swt/dna-web-jcr-rest-client-0.6-SNAPSHOT-jar-with-dependencies.jar
branches/eclipse/org.jboss.dna.publish.ui.swt/dna-web-jcr-rest-client-0.6-SNAPSHOT-sources.jar
branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/IUiConstants.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.properties
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/Utils.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaContentProvider.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishPage.java
Log:
Added a DNA preference page where the user can enter file extensions. Any file with a matching extension will not be included in any publishing operation.
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/dna-web-jcr-rest-client-0.6-SNAPSHOT-jar-with-dependencies.jar
===================================================================
(Binary files differ)
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/dna-web-jcr-rest-client-0.6-SNAPSHOT-sources.jar
===================================================================
(Binary files differ)
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml 2009-09-03 20:55:13 UTC (rev 1193)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml 2009-09-04 20:57:55 UTC (rev 1194)
@@ -131,4 +131,13 @@
<toc file="docs/toc.xml" primary="true" />
</extension>
+<!-- Preference Page -->
+ <extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ name="%dnaCategory"
+ class="org.jboss.dna.web.jcr.rest.client.swt.preferences.DnaPreferencePage"
+ id="dnaPreferencePage">
+ </page>
+ </extension>
</plugin>
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/IUiConstants.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/IUiConstants.java 2009-09-03 20:55:13 UTC (rev 1193)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/IUiConstants.java 2009-09-04 20:57:55 UTC (rev 1194)
@@ -112,4 +112,15 @@
*/
String DNA_PUBLISHING_JOB_FAMILY = "dna.publishing.job.family"; //$NON-NLS-1$
+ //
+ // Preferences
+ //
+
+ /**
+ * A preference for a list of file extensions that will not be part of publishing operations.
+ *
+ * @since 0.6
+ */
+ String FILTERED_FILE_EXTENSIONS_PREFERENCE = "dna.preference.filteredFileExtensions"; //$NON-NLS-1$
+
}
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.java 2009-09-03 20:55:13 UTC (rev 1193)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.java 2009-09-04 20:57:55 UTC (rev 1194)
@@ -48,6 +48,11 @@
public static I18n dnaConsoleName;
public static I18n dnaConsoleProblemCreatingHyperlinkMsg;
public static I18n dnaConsoleFilePathNotFoundMsg;
+
+ public static I18n dnaPreferencePageFilteredFileExtensionsDescription;
+ public static I18n dnaPreferencePageFilteredFileExtensionsLabel;
+ public static I18n dnaPreferencePageFilteredFileExtensionsMessage;
+ public static I18n dnaPreferencePageFilteredFileExtensionsTitle;
public static I18n editServerActionText;
public static I18n editServerActionToolTip;
@@ -55,6 +60,9 @@
public static I18n errorDialogTitle;
public static I18n missingImage;
+
+ public static I18n newFileExtensionDialogLabel;
+ public static I18n newFileExtensionDialogTitle;
public static I18n newServerActionText;
public static I18n newServerActionToolTip;
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.properties 2009-09-03 20:55:13 UTC (rev 1193)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.properties 2009-09-04 20:57:55 UTC (rev 1194)
@@ -40,11 +40,19 @@
dnaConsoleName = DNA
dnaConsoleProblemCreatingHyperlinkMsg = Unexpected problem creating hyperlink in DNA Console view
dnaConsoleFilePathNotFoundMsg = A hyperlink could not be created in the DNA Message Console because the file path of "{0}" could not be found.
+
+dnaPreferencePageFilteredFileExtensionsDescription = Add, remove, or edit the filtered file extensions. Files with matching extensions will NOT be published to DNA repositories.
+dnaPreferencePageFilteredFileExtensionsLabel = Filtered File Extensions:
+dnaPreferencePageFilteredFileExtensionsMessage = DNA
+dnaPreferencePageFilteredFileExtensionsTitle = DNA Filtered File Extensions
errorDialogTitle = Error
missingImage = The following image cannot be found "{0}"
+newFileExtensionDialogLabel = File Extension:
+newFileExtensionDialogTitle = New Filtered File Extension
+
newServerActionText = New Server
newServerActionToolTip = Create a new server
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/Utils.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/Utils.java 2009-09-03 20:55:13 UTC (rev 1193)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/Utils.java 2009-09-04 20:57:55 UTC (rev 1194)
@@ -23,6 +23,16 @@
*/
package org.jboss.dna.web.jcr.rest.client.swt;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
@@ -44,6 +54,24 @@
// ===========================================================================================================================
/**
+ * @param tokens the tokens being combined into one value
+ * @param delimiter the character inserted to separate each token
+ * @return the tokens separated by the delimiter
+ * @since 0.6
+ */
+ public static String combineTokens( String[] tokens,
+ char delimiter ) {
+ CheckArg.isNotNull(tokens, "tokens"); //$NON-NLS-1$
+ StringBuilder value = new StringBuilder();
+
+ for (String token : tokens) {
+ value.append(token).append(delimiter);
+ }
+
+ return value.toString();
+ }
+
+ /**
* Sizes the shell to the minimum of it's current size or the width and height display percentages.
*
* @param shell the shell being resized (if necessary) and located
@@ -113,6 +141,33 @@
}
/**
+ * @param container the project or folder whose files are being requested
+ * @param recurse the flag indicating if child containers should be traversed
+ * @return the list of files contained in the specified container (never <code>null</code>)
+ * @throws CoreException if there is a problem finding the files
+ * @since 0.6
+ */
+ public static List<IFile> findFiles( IContainer container,
+ boolean recurse ) throws CoreException {
+ List<IFile> result = new ArrayList<IFile>();
+
+ for (IResource member : container.members()) {
+ if (recurse && (member instanceof IContainer)) {
+ // don't select closed projects
+ if ((member instanceof IProject) && !((IProject)member).isOpen()) {
+ continue;
+ }
+
+ result.addAll(findFiles((IContainer)member, recurse));
+ } else if ((member instanceof IFile) && ((IFile)member).getLocation().toFile().exists()) {
+ result.add((IFile)member);
+ }
+ }
+
+ return result;
+ }
+
+ /**
* The OK status does not have an image.
*
* @param status the status whose image is being requested (never <code>null</code>)
@@ -139,6 +194,32 @@
}
/**
+ * @param string the string whose tokens are being requested (may be <code>null</code>)
+ * @param delimiters the delimiters that separate the tokens (never <code>null</code>)
+ * @param removeDuplicates a flag indicating if duplicate tokens should be removed
+ * @return the tokens (never <code>null</code>)
+ * @since 0.6
+ */
+ public static String[] getTokens( String string,
+ String delimiters,
+ boolean removeDuplicates ) {
+ CheckArg.isNotNull(delimiters, "delimiters"); //$NON-NLS-1$
+
+ if (string == null) {
+ return new String[0];
+ }
+
+ Collection<String> tokens = removeDuplicates ? new TreeSet<String>() : new ArrayList<String>();
+ StringTokenizer st = new StringTokenizer(string, delimiters);
+
+ while (st.hasMoreTokens()) {
+ tokens.add(st.nextToken());
+ }
+
+ return tokens.toArray(new String[tokens.size()]);
+ }
+
+ /**
* The image can be used to decorate an existing image.
*
* @param status the status whose image overlay is being requested (never <code>null</code>)
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/DnaPreferencePage.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/DnaPreferencePage.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/DnaPreferencePage.java 2009-09-04 20:57:55 UTC (rev 1194)
@@ -0,0 +1,177 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.web.jcr.rest.client.swt.preferences;
+
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.DNA_IMAGE_16x;
+import static org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n.dnaPreferencePageFilteredFileExtensionsDescription;
+import static org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n.dnaPreferencePageFilteredFileExtensionsMessage;
+import static org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n.dnaPreferencePageFilteredFileExtensionsTitle;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.jboss.dna.web.jcr.rest.client.swt.Activator;
+
+/**
+ * The <code>DnaPreferencePage</code> is the UI for managing all DNA-related preferences.
+ *
+ * @since 0.6
+ */
+public final class DnaPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The editor used to manage the list of file extensions.
+ *
+ * @since 0.6
+ */
+ private ExtensionEditor editor;
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.preference.PreferencePage#createContents(org.eclipse.swt.widgets.Composite)
+ * @since 0.6
+ */
+ @Override
+ protected Control createContents( Composite parent ) {
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayout(new GridLayout(2, false));
+ panel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ // create the editor
+ this.editor = new ExtensionEditor(panel);
+ this.editor.setPreferenceStore(getPreferenceStore());
+ this.editor.getListControl(panel).setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ // populate the editor
+ this.editor.load();
+
+ return panel;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.DialogPage#getDescription()
+ * @since 0.6
+ */
+ @Override
+ public String getDescription() {
+ return dnaPreferencePageFilteredFileExtensionsDescription.text();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.DialogPage#getImage()
+ * @since 0.6
+ */
+ @Override
+ public Image getImage() {
+ return Activator.getDefault().getImage(DNA_IMAGE_16x);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.DialogPage#getMessage()
+ * @since 0.6
+ */
+ @Override
+ public String getMessage() {
+ return dnaPreferencePageFilteredFileExtensionsMessage.text();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.preference.PreferencePage#getPreferenceStore()
+ * @since 0.6
+ */
+ @Override
+ public IPreferenceStore getPreferenceStore() {
+ return PrefUtils.getPreferenceStore();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.DialogPage#getTitle()
+ * @since 0.6
+ */
+ @Override
+ public String getTitle() {
+ return dnaPreferencePageFilteredFileExtensionsTitle.text();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IWorkbenchPreferencePage#init(org.eclipse.ui.IWorkbench)
+ * @since 0.6
+ */
+ @Override
+ public void init( IWorkbench workbench ) {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.preference.PreferencePage#performDefaults()
+ * @since 0.6
+ */
+ @Override
+ protected void performDefaults() {
+ this.editor.loadDefault();
+ super.performDefaults();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.preference.PreferencePage#performOk()
+ * @since 0.6
+ */
+ @Override
+ public boolean performOk() {
+ this.editor.store();
+ return super.performOk();
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/DnaPreferencePage.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/ExtensionEditor.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/ExtensionEditor.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/ExtensionEditor.java 2009-09-04 20:57:55 UTC (rev 1194)
@@ -0,0 +1,110 @@
+package org.jboss.dna.web.jcr.rest.client.swt.preferences;
+
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.FILTERED_FILE_EXTENSIONS_PREFERENCE;
+import static org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n.dnaPreferencePageFilteredFileExtensionsLabel;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.TreeSet;
+import org.eclipse.jface.preference.ListEditor;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Composite;
+import org.jboss.dna.web.jcr.rest.client.swt.Utils;
+
+/**
+ * The <code>ExtensionEditor</code> is an editor for managing a set of file extensions.
+ *
+ * @since 0.6
+ */
+public final class ExtensionEditor extends ListEditor {
+
+ // =======================================================================================================================
+ // Constants
+ // =======================================================================================================================
+
+ /**
+ * The delimiter used to separate file extensions when saved to the preference store.
+ *
+ * @since 0.6
+ */
+ private static final char DELIM = ',';
+
+ // =======================================================================================================================
+ // Fields
+ // =======================================================================================================================
+
+ /**
+ * The current set of file extensions.
+ *
+ * @since 0.6
+ */
+ private final Set<String> extensions;
+
+ // =======================================================================================================================
+ // Constructors
+ // =======================================================================================================================
+
+ /**
+ * @param parent the parent control
+ * @since 0.6
+ */
+ public ExtensionEditor( Composite parent ) {
+ super(FILTERED_FILE_EXTENSIONS_PREFERENCE, dnaPreferencePageFilteredFileExtensionsLabel.text(), parent);
+ this.extensions = new TreeSet<String>();
+ }
+
+ // =======================================================================================================================
+ // Methods
+ // =======================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.preference.ListEditor#createList(java.lang.String[])
+ * @since 0.6
+ */
+ @Override
+ protected String createList( String[] items ) {
+ return Utils.combineTokens(items, DELIM);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.preference.ListEditor#getNewInputObject()
+ * @since 0.6
+ */
+ @Override
+ protected String getNewInputObject() {
+ NewFileExtensionDialog dialog = new NewFileExtensionDialog(getShell());
+
+ if (dialog.open() == Window.OK) {
+ String extension = dialog.getFileExtension();
+
+ // add new extension
+ if (extension != null) {
+ this.extensions.add(extension);
+ return extension;
+ }
+ }
+
+ // user canceled dialog
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.preference.ListEditor#parseString(java.lang.String)
+ * @since 0.6
+ */
+ @Override
+ protected String[] parseString( String stringList ) {
+ String[] values = Utils.getTokens(stringList, Character.toString(DELIM), true);
+
+ this.extensions.clear();
+ this.extensions.addAll(Arrays.asList(values));
+
+ return values;
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/ExtensionEditor.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/NewFileExtensionDialog.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/NewFileExtensionDialog.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/NewFileExtensionDialog.java 2009-09-04 20:57:55 UTC (rev 1194)
@@ -0,0 +1,156 @@
+package org.jboss.dna.web.jcr.rest.client.swt.preferences;
+
+import static org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n.newFileExtensionDialogLabel;
+import static org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n.newFileExtensionDialogTitle;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A <code>NewFileExtensionDialog</code> allows the user to enter a file extension that they wish to be filtered out of all
+ * publishing operations.
+ *
+ * @since 0.6
+ */
+public final class NewFileExtensionDialog extends Dialog implements ModifyListener, VerifyListener {
+
+ // =======================================================================================================================
+ // Fields
+ // =======================================================================================================================
+
+ /**
+ * The contents of the extension text field.
+ *
+ * @since 0.6
+ */
+ private String extension;
+
+ // =======================================================================================================================
+ // Constructors
+ // =======================================================================================================================
+
+ /**
+ * @param parentShell the parent shell
+ * @since 0.6
+ */
+ protected NewFileExtensionDialog( Shell parentShell ) {
+ super(parentShell);
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ }
+
+ // =======================================================================================================================
+ // Methods
+ // =======================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
+ * @since 0.6
+ */
+ @Override
+ protected void configureShell( Shell newShell ) {
+ newShell.setText(newFileExtensionDialogTitle.text());
+ super.configureShell(newShell);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#createButton(org.eclipse.swt.widgets.Composite, int, java.lang.String, boolean)
+ * @since 0.6
+ */
+ @Override
+ protected Button createButton( Composite parent,
+ int id,
+ String label,
+ boolean defaultButton ) {
+ Button button = super.createButton(parent, id, label, defaultButton);
+
+ // disable OK button initially
+ if (id == OK) {
+ button.setEnabled(false);
+ }
+
+ return button;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
+ * @since 0.6
+ */
+ @Override
+ protected Control createDialogArea( Composite parent ) {
+ Composite panel = (Composite)super.createDialogArea(parent);
+ Composite pnlEditor = new Composite(panel, SWT.NONE);
+ pnlEditor.setLayout(new GridLayout(2, false));
+ pnlEditor.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ Label label = new Label(pnlEditor, SWT.NONE);
+ label.setText(newFileExtensionDialogLabel.text());
+
+ Text textField = new Text(pnlEditor, SWT.BORDER);
+ textField.setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
+ textField.addVerifyListener(this);
+ textField.addModifyListener(this);
+
+ return panel;
+ }
+
+ /**
+ * @return the file extension or <code>null</code> if dialog was canceled
+ * @since 0.6
+ */
+ public String getFileExtension() {
+ if (getReturnCode() == OK) {
+ return this.extension;
+ }
+
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.ModifyListener#modifyText(org.eclipse.swt.events.ModifyEvent)
+ * @since 0.6
+ */
+ @Override
+ public void modifyText( ModifyEvent event ) {
+ // disable OK button if text field does not have any characters
+ this.extension = ((Text)event.widget).getText();
+ boolean enable = (this.extension.length() != 0);
+
+ if (getButton(OK).getEnabled() != enable) {
+ getButton(OK).setEnabled(enable);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.VerifyListener#verifyText(org.eclipse.swt.events.VerifyEvent)
+ * @since 0.6
+ */
+ @Override
+ public void verifyText( VerifyEvent event ) {
+ // only allow letters, numbers, backspace, and delete
+ if (!Character.isLetterOrDigit(event.character) && (event.character != '\b') && (event.character != '\u007F')) {
+ event.doit = false;
+ }
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/NewFileExtensionDialog.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/PrefUtils.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/PrefUtils.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/PrefUtils.java 2009-09-04 20:57:55 UTC (rev 1194)
@@ -0,0 +1,100 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.web.jcr.rest.client.swt.preferences;
+
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.FILTERED_FILE_EXTENSIONS_PREFERENCE;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.web.jcr.rest.client.swt.Activator;
+import org.jboss.dna.web.jcr.rest.client.swt.Utils;
+
+/**
+ * The <code>PrefUtils</code> class provides common utilities relating to preferences. This class assumes the Eclipse runtime
+ * platform is running.
+ *
+ * @since 0.6
+ */
+public final class PrefUtils {
+
+ // =======================================================================================================================
+ // Class Methods
+ // =======================================================================================================================
+
+ /**
+ * @return the file extensions being filtered out of publishing operations (never null)
+ * @since 0.6
+ */
+ public static String[] getFilteredFileExtensions() {
+ return getListPropertyValue(FILTERED_FILE_EXTENSIONS_PREFERENCE, ',', true);
+ }
+
+ /**
+ * @param propertyId the property name whose list values are being requested
+ * @param delimiter the character separating the items in the property value
+ * @param removeDuplicates a flag indicating if duplicate items should be removed
+ * @return the property value items (never <code>null</code>)
+ * @since 0.6
+ */
+ public static String[] getListPropertyValue( String propertyId,
+ char delimiter,
+ boolean removeDuplicates ) {
+ CheckArg.isNotNull(propertyId, "propertyId"); //$NON-NLS-1$
+ return Utils.getTokens(getPreferenceStore().getString(propertyId), Character.toString(delimiter), removeDuplicates);
+ }
+
+ /**
+ * @return the plugin preference store
+ * @since 0.6
+ */
+ public static IPreferenceStore getPreferenceStore() {
+ return Activator.getDefault().getPreferenceStore();
+ }
+
+ /**
+ * @param propertyId the property name being set (never <code>null</code>)
+ * @param items the items used to create the property value (never <code>null</code>)
+ * @param delimiter the character to use to separate the items
+ * @since 0.6
+ */
+ public static void setListPropertyValue( String propertyId,
+ String[] items,
+ char delimiter ) {
+ CheckArg.isNotNull(propertyId, "propertyId"); //$NON-NLS-1$
+ CheckArg.isNotNull(items, "items"); //$NON-NLS-1$
+ getPreferenceStore().setValue(propertyId, Utils.combineTokens(items, delimiter));
+ }
+
+ // =======================================================================================================================
+ // Constructors
+ // =======================================================================================================================
+
+ /**
+ * Don't allow construction.
+ *
+ * @since 0.6
+ */
+ private PrefUtils() {
+ // nothing to do
+ }
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/preferences/PrefUtils.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaContentProvider.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaContentProvider.java 2009-09-03 20:55:13 UTC (rev 1193)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaContentProvider.java 2009-09-04 20:57:55 UTC (rev 1194)
@@ -162,22 +162,24 @@
public Object[] getChildren( Object parentElement ) {
assert (parentElement instanceof IDnaObject);
- try {
- if ((parentElement instanceof Server) && (getServerManager() != null)) {
- return getServerManager().getRepositories((Server)parentElement).toArray();
+ if (getServerManager() != null) {
+ try {
+ if ((parentElement instanceof Server) && getServerManager().ping((Server)parentElement).isOk()) {
+ return getServerManager().getRepositories((Server)parentElement).toArray();
+ }
+ } catch (Exception e) {
+ String msg = RestClientI18n.serverManagerGetRepositoriesExceptionMsg.text(((Server)parentElement).getShortDescription());
+ Activator.getDefault().log(new Status(Severity.ERROR, msg, e));
}
- } catch (Exception e) {
- String msg = RestClientI18n.serverManagerGetRepositoriesExceptionMsg.text(((Server)parentElement).getShortDescription());
- Activator.getDefault().log(new Status(Severity.ERROR, msg, e));
- }
- try {
- if ((parentElement instanceof Repository) && (getServerManager() != null)) {
- return getServerManager().getWorkspaces((Repository)parentElement).toArray();
+ try {
+ if (parentElement instanceof Repository) {
+ return getServerManager().getWorkspaces((Repository)parentElement).toArray();
+ }
+ } catch (Exception e) {
+ String msg = RestClientI18n.serverManagerGetWorkspacesExceptionMsg.text();
+ Activator.getDefault().log(new Status(Severity.ERROR, msg, e));
}
- } catch (Exception e) {
- String msg = RestClientI18n.serverManagerGetWorkspacesExceptionMsg.text();
- Activator.getDefault().log(new Status(Severity.ERROR, msg, e));
}
return new Object[0];
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishPage.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishPage.java 2009-09-03 20:55:13 UTC (rev 1193)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishPage.java 2009-09-04 20:57:55 UTC (rev 1194)
@@ -64,7 +64,9 @@
import org.jboss.dna.web.jcr.rest.client.domain.Workspace;
import org.jboss.dna.web.jcr.rest.client.swt.Activator;
import org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n;
+import org.jboss.dna.web.jcr.rest.client.swt.Utils;
import org.jboss.dna.web.jcr.rest.client.swt.actions.NewServerAction;
+import org.jboss.dna.web.jcr.rest.client.swt.preferences.PrefUtils;
import org.jboss.dna.web.jcr.rest.client.swt.wizards.PublishJob.Type;
/**
@@ -90,33 +92,6 @@
// ===========================================================================================================================
/**
- * @param container the project or folder whose files are being requested
- * @param recurse the flag indicating if child containers should be traversed
- * @return the list of files contained in the specified container (never <code>null</code>)
- * @throws CoreException if there is a problem finding the files
- * @since 0.6
- */
- private static List<IFile> findFiles( IContainer container,
- boolean recurse ) throws CoreException {
- List<IFile> result = new ArrayList<IFile>();
-
- for (IResource member : container.members()) {
- if (recurse && (member instanceof IContainer)) {
- // don't publish closed projects
- if ((member instanceof IProject) && !((IProject)member).isOpen()) {
- continue;
- }
-
- result.addAll(findFiles((IContainer)member, recurse));
- } else if ((member instanceof IFile) && ((IFile)member).getLocation().toFile().exists()) {
- result.add((IFile)member);
- }
- }
-
- return result;
- }
-
- /**
* Processes the specified list of files and for (1) each file found adds it to the result and (2) for each project or folder
* adds all contained files. For projects and folders processing will be recursive based on saved wizard settings.
*
@@ -220,14 +195,14 @@
Map<IContainer, List<IFile>> parentMap = projectMap.get(project);
if (parentMap == null) {
- result.addAll(findFiles(project, recurse));
+ result.addAll(Utils.findFiles(project, recurse));
} else {
// process folders with no folder entries
for (IContainer folder : parentMap.keySet()) {
List<IFile> files = parentMap.get(folder);
if (files == null) {
- result.addAll(findFiles(folder, recurse));
+ result.addAll(Utils.findFiles(folder, recurse));
}
}
}
@@ -282,6 +257,13 @@
private List<IFile> files;
/**
+ * Indicates if the selected files should be filtered based on their file extension.
+ *
+ * @since 0.6
+ */
+ private boolean filterFiles = true;
+
+ /**
* The control containing all the files being published or unpublished.
*
* @since 0.6
@@ -371,7 +353,8 @@
public PublishPage( Type type,
List<IResource> resources ) throws CoreException {
super(PublishPage.class.getSimpleName());
- setTitle((type == Type.PUBLISH) ? RestClientI18n.publishPagePublishTitle.text() : RestClientI18n.publishPageUnpublishTitle.text());
+ setTitle((type == Type.PUBLISH) ? RestClientI18n.publishPagePublishTitle.text()
+ : RestClientI18n.publishPageUnpublishTitle.text());
setPageComplete(false);
this.type = type;
@@ -577,7 +560,8 @@
* @since 0.6
*/
void updateInitialMessage() {
- String msg = ((this.type == Type.PUBLISH) ? RestClientI18n.publishPagePublishOkStatusMsg.text() : RestClientI18n.publishPageUnpublishOkStatusMsg.text());
+ String msg = ((this.type == Type.PUBLISH) ? RestClientI18n.publishPagePublishOkStatusMsg.text()
+ : RestClientI18n.publishPageUnpublishOkStatusMsg.text());
if (msg.equals(getMessage())) {
updateState();
@@ -700,18 +684,37 @@
* Populates the list of files to be published based on the recurse flag and the list of workspace selected resources.
* Pre-condition is that {@link #processResources(List, boolean)} has been called.
*
+ * @return the number of files filtered out
* @since 0.6
*/
- private void loadFiles() {
- String[] data = new String[this.files.size()];
- int i = 0;
+ private int loadFiles() {
+ this.lstResources.removeAll();
+ String[] filteredExtensions = null;
+ int numFiltered = 0;
+
+ if (this.filterFiles) {
+ filteredExtensions = PrefUtils.getFilteredFileExtensions();
+ }
+
+ LOADING:
for (IResource resource : this.files) {
- data[i] = resource.getFullPath().toString();
- ++i;
+ String filePath = resource.getFullPath().toString();
+
+ // filter if necessary
+ if (filteredExtensions != null) {
+ for (String ext : filteredExtensions) {
+ if (filePath.endsWith('.' + ext)) {
+ ++numFiltered;
+ continue LOADING; // don't add file
+ }
+ }
+ }
+
+ this.lstResources.add(filePath);
}
- this.lstResources.setItems(data);
+ return numFiltered;
}
/**
@@ -934,7 +937,8 @@
// set initial message
if (this.status.isOk()) {
- String msg = ((this.type == Type.PUBLISH) ? RestClientI18n.publishPagePublishOkStatusMsg.text() : RestClientI18n.publishPageUnpublishOkStatusMsg.text());
+ String msg = ((this.type == Type.PUBLISH) ? RestClientI18n.publishPagePublishOkStatusMsg.text()
+ : RestClientI18n.publishPageUnpublishOkStatusMsg.text());
setMessage(msg, IMessageProvider.NONE);
} else {
setMessage(this.status.getMessage(), IMessageProvider.ERROR);
@@ -998,19 +1002,24 @@
Severity severity = Severity.ERROR;
if ((this.resources == null) || this.resources.isEmpty() || this.files.isEmpty()) {
- msg = ((type == Type.PUBLISH) ? RestClientI18n.publishPageNoResourcesToPublishStatusMsg.text() : RestClientI18n.publishPageNoResourcesToUnpublishStatusMsg.text());
+ msg = ((type == Type.PUBLISH) ? RestClientI18n.publishPageNoResourcesToPublishStatusMsg.text()
+ : RestClientI18n.publishPageNoResourcesToUnpublishStatusMsg.text());
} else if (this.server == null) {
int count = this.cbxServer.getItemCount();
- msg = ((count == 0) ? RestClientI18n.publishPageNoAvailableServersStatusMsg.text() : RestClientI18n.publishPageMissingServerStatusMsg.text());
+ msg = ((count == 0) ? RestClientI18n.publishPageNoAvailableServersStatusMsg.text()
+ : RestClientI18n.publishPageMissingServerStatusMsg.text());
} else if (this.repository == null) {
int count = this.cbxRepository.getItemCount();
- msg = ((count == 0) ? RestClientI18n.publishPageNoAvailableRepositoriesStatusMsg.text() : RestClientI18n.publishPageMissingRepositoryStatusMsg.text());
+ msg = ((count == 0) ? RestClientI18n.publishPageNoAvailableRepositoriesStatusMsg.text()
+ : RestClientI18n.publishPageMissingRepositoryStatusMsg.text());
} else if (this.workspace == null) {
int count = this.cbxWorkspace.getItemCount();
- msg = ((count == 0) ? RestClientI18n.publishPageNoAvailableWorkspacesStatusMsg.text() : RestClientI18n.publishPageMissingWorkspaceStatusMsg.text());
+ msg = ((count == 0) ? RestClientI18n.publishPageNoAvailableWorkspacesStatusMsg.text()
+ : RestClientI18n.publishPageMissingWorkspaceStatusMsg.text());
} else {
severity = Severity.OK;
- msg = ((type == Type.PUBLISH) ? RestClientI18n.publishPagePublishOkStatusMsg.text() : RestClientI18n.publishPageUnpublishOkStatusMsg.text());
+ msg = ((type == Type.PUBLISH) ? RestClientI18n.publishPagePublishOkStatusMsg.text()
+ : RestClientI18n.publishPageUnpublishOkStatusMsg.text());
}
this.status = new Status(severity, msg, null);
14 years, 8 months
DNA SVN: r1193 - in trunk: extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn and 1 other directory.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-09-03 16:55:13 -0400 (Thu, 03 Sep 2009)
New Revision: 1193
Modified:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java
Log:
DNA-505 Svn Repository Source with NPE and other issues while opening connection through Jcr
There really isn't a durable UUID available for each file in SVN (there is a single UUID for each repository, though). And so the SVN connector does not return a 'jcr:uuid' property for the 'jcr:content' node, and this fouls up the SessionCache implementation. However, while 'nt:file' and 'nt:folder' are not referenceable, 'nt:resource' is. But lucky for us that the JCR spec does not require that the 'jcr:content' node has a type of 'nt:resource'; it merely says:
A common approach is to make the jcr:content a node of type nt:resource. (Section 6.7.22.6 of the 1.0.1 version of the JCR specification, page 160.)
So, a solution is to do the same thing we did in the file system connector: use a 'dna:resource' node type that is identical to 'nt:resource' except that it does not extend 'mix:referenceable'.
Modified: trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
===================================================================
--- trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java 2009-09-03 20:01:08 UTC (rev 1192)
+++ trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java 2009-09-03 20:55:13 UTC (rev 1193)
@@ -26,7 +26,10 @@
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
+import javax.jcr.Node;
import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
import javax.jcr.Session;
import org.jboss.dna.connector.svn.SVNRepositorySource;
import org.jboss.dna.graph.SecurityContext;
@@ -92,6 +95,18 @@
assertThat(this.session.getRootNode().getNode("dna-graph"), is(notNullValue()));
}
+ @Test
+ public void shouldProvideAccessToJcrDataNodeUnderFileNode() throws Exception {
+ System.out.println("Getting /pom.xml/jcr:content and then walking its properties ...");
+ Node resourceNodeOfPomFile = this.session.getRootNode().getNode("pom.xml/jcr:content");
+ assertThat(resourceNodeOfPomFile, is(notNullValue()));
+
+ for (PropertyIterator iter = resourceNodeOfPomFile.getProperties(); iter.hasNext();) {
+ Property property = iter.nextProperty();
+ assertThat(property.getName(), is(notNullValue()));
+ }
+ }
+
protected class MyCustomSecurityContext implements SecurityContext {
/**
* {@inheritDoc}
Modified: trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-09-03 20:01:08 UTC (rev 1192)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-09-03 20:55:13 UTC (rev 1193)
@@ -36,6 +36,7 @@
import org.jboss.dna.common.util.Logger;
import org.jboss.dna.connector.scm.ScmAction;
import org.jboss.dna.connector.scm.ScmActionFactory;
+import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.JcrLexicon;
import org.jboss.dna.graph.JcrNtLexicon;
@@ -214,7 +215,11 @@
SVNDirEntry entry = getEntryInfo(workspaceRoot, contentPath);
if (entry != null) {
// The request is to get properties of the "jcr:content" child node ...
- addProperty(properties, factory, JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.RESOURCE);
+ // Do NOT use "nt:resource", since it extends "mix:referenceable". The JCR spec
+ // does not require that "jcr:content" is of type "nt:resource", but rather just
+ // suggests it. Therefore, we can use "dna:resource", which is identical to
+ // "nt:resource" except it does not extend "mix:referenceable"
+ addProperty(properties, factory, JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE);
addProperty(properties, factory, JcrLexicon.LAST_MODIFIED, dateFactory.create(entry.getDate()));
}
14 years, 8 months
DNA SVN: r1192 - in trunk: dna-integration-tests/src/test/resources/tck/jpa and 3 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-09-03 16:01:08 -0400 (Thu, 03 Sep 2009)
New Revision: 1192
Modified:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/JcrRepositoryWithJpaConfigurationTest.java
trunk/dna-integration-tests/src/test/resources/tck/jpa/configRepository.xml
trunk/docs/reference/src/main/docbook/en-US/content/connectors/jdbc_storage.xml
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorCreateWorkspacesTest.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorNoCreateWorkspaceTest.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorWritingTest.java
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java
Log:
DNA-510 The JPA RepositorySource should provide way to specify the 'hibernate.hbm2ddl.auto' property
Applied a modified version of the patch. Note that the default 'autoGenerateSchema' property value is now 'validate', since that is the least disruptive on an existing database (such as a production database). Therefore, note that 'create' used to be the default, so this may affect some users.
Updated the JPA Connector chapter in the Reference Guide to include the new property.
Modified: trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/JcrRepositoryWithJpaConfigurationTest.java
===================================================================
--- trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/JcrRepositoryWithJpaConfigurationTest.java 2009-09-03 19:07:26 UTC (rev 1191)
+++ trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/JcrRepositoryWithJpaConfigurationTest.java 2009-09-03 20:01:08 UTC (rev 1192)
@@ -98,7 +98,7 @@
.setProperty("largeValueSizeInBytes", 150)
.setProperty("compressData", true)
.setProperty("referentialIntegrityEnforced", true)
- .setProperty("autoDdl", "create")
+ .setProperty("autoGenerateSchema", "create")
.setProperty("showSql", false);
// Set up the JCR repository ...
Modified: trunk/dna-integration-tests/src/test/resources/tck/jpa/configRepository.xml
===================================================================
--- trunk/dna-integration-tests/src/test/resources/tck/jpa/configRepository.xml 2009-09-03 19:07:26 UTC (rev 1191)
+++ trunk/dna-integration-tests/src/test/resources/tck/jpa/configRepository.xml 2009-09-03 20:01:08 UTC (rev 1192)
@@ -47,6 +47,7 @@
dna:compressData="true"
dna:predefinedWorkspaceNames="default"
dna:showSql="false"
+ dna:autoGenerateSchema="create"
dna:defaultWorkspaceName="default"/>
</dna:sources>
<!--
Modified: trunk/docs/reference/src/main/docbook/en-US/content/connectors/jdbc_storage.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/connectors/jdbc_storage.xml 2009-09-03 19:07:26 UTC (rev 1191)
+++ trunk/docs/reference/src/main/docbook/en-US/content/connectors/jdbc_storage.xml 2009-09-03 20:01:08 UTC (rev 1192)
@@ -207,6 +207,27 @@
</entry>
</row>
<row>
+ <entry>autoGenerateSchema</entry>
+ <entry>
+ Sets the Hibernate setting dictating what it does with the database schema upon first connection. Valid values are as
+ follows (though the value is not checked):
+ <itemizedlist>
+ <listitem><para>"<code>create</code>" - Create the database schema objects when the &EntityManagerFactory; is created (actually
+ when Hibernate's SessionFactory is created by the entity manager factory). If a file named "import.sql" exists in
+ the root of the class path (e.g., '/import.sql') Hibernate will read and execute the SQL statements in this file after it
+ has created the database objects. Note that Hibernate first delete all tables, constraints, or any other database object
+ that is going to be created in the process of building the schema.</para></listitem>
+ <listitem><para>"<code>create-drop</code>" - Same as "<code>create</code>", except that the schema will be dropped after the
+ &EntityManagerFactory; is closed.</para></listitem>
+ <listitem><para>"<code>update</code>" - Attempt to update the database structure to the current mapping (but does not read and invoke
+ the SQL statements from "import.sql"). <emphasis>Use with caution.</emphasis></para></listitem>
+ <listitem><para>"<code>validate</code>" - Validates the existing schema with the current entities configuration, but does not make any
+ changes to the schema (and does not read and invoke the SQL statements from "import.sql"). This is often the proper setting
+ to use in production, and thus this is the default value.</para></listitem>
+ </itemizedlist>
+ </entry>
+ </row>
+ <row>
<entry>retryLimit</entry>
<entry>Optional property that, if used, defines the number of times that any single operation on a &RepositoryConnection; to this source should be retried
following a communication failure.
@@ -235,7 +256,8 @@
.setDescription("The database store for our content")
.setProperty("dialect", "org.hibernate.dialect.MySQLDialect")
.setProperty("dataSourceJndiName", "java:/MyDataSource")
- .setProperty("nameOfDefaultWorkspace", "My Default Workspace");
+ .setProperty("nameOfDefaultWorkspace", "My Default Workspace")
+ .setProperty("autoGenerateSchema", "validate");
]]></programlisting>
<para>
Of course, setting other more advanced properties would entail calling <code>setProperty(...)</code> for each. Since almost all
Modified: trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java 2009-09-03 19:07:26 UTC (rev 1191)
+++ trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java 2009-09-03 20:01:08 UTC (rev 1192)
@@ -43,6 +43,7 @@
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import net.jcip.annotations.Immutable;
+import org.hibernate.SessionFactory;
import org.hibernate.ejb.Ejb3Configuration;
import org.jboss.dna.common.i18n.I18n;
import org.jboss.dna.common.util.CheckArg;
@@ -123,6 +124,7 @@
protected static final String DEFAULT_WORKSPACE = "defaultWorkspace";
protected static final String PREDEFINED_WORKSPACE_NAMES = "predefinedWorkspaceNames";
protected static final String ALLOW_CREATING_WORKSPACES = "allowCreatingWorkspaces";
+ protected static final String AUTO_GENERATE_SCHEMA = "autoGenerateSchema";
/**
* This source supports events.
@@ -174,6 +176,12 @@
private static final boolean DEFAULT_ENFORCE_REFERENTIAL_INTEGRITY = true;
/**
+ * The initial {@link #getAutoGenerateSchema() automatic schema generation setting} is "{@value} ", unless otherwise
+ * specified.
+ */
+ public static final String DEFAULT_AUTO_GENERATE_SCHEMA = "validate";
+
+ /**
* The first serialized version of this source.
*/
private static final long serialVersionUID = 1L;
@@ -199,6 +207,7 @@
private volatile boolean showSql = DEFAULT_SHOW_SQL;
private volatile boolean compressData = DEFAULT_COMPRESS_DATA;
private volatile boolean referentialIntegrityEnforced = DEFAULT_ENFORCE_REFERENTIAL_INTEGRITY;
+ private volatile String autoGenerateSchema = DEFAULT_AUTO_GENERATE_SCHEMA;
private volatile String defaultWorkspace = DEFAULT_NAME_OF_DEFAULT_WORKSPACE;
private volatile String[] predefinedWorkspaces = new String[] {};
private volatile RepositorySourceCapabilities capabilities = new RepositorySourceCapabilities(
@@ -286,6 +295,40 @@
}
/**
+ * Get the Hibernate setting dictating what it does with the database schema upon first connection. For more information, see
+ * {@link #setAutoGenerateSchema(String)}.
+ *
+ * @return the setting; never null
+ */
+ public String getAutoGenerateSchema() {
+ return this.autoGenerateSchema;
+ }
+
+ /**
+ * Sets the Hibernate setting dictating what it does with the database schema upon first connection. Valid values are as
+ * follows (though the value is not checked):
+ * <ul>
+ * <li>"<code>create</code>" - Create the database schema objects when the {@link EntityManagerFactory} is created (actually
+ * when Hibernate's {@link SessionFactory} is created by the entity manager factory). If a file named "import.sql" exists in
+ * the root of the class path (e.g., '/import.sql') Hibernate will read and execute the SQL statements in this file after it
+ * has created the database objects. Note that Hibernate first delete all tables, constraints, or any other database object
+ * that is going to be created in the process of building the schema.</li>
+ * <li>"<code>create-drop</code>" - Same as "<code>create</code>", except that the schema will be dropped after the
+ * {@link EntityManagerFactory} is closed.</li>
+ * <li>"<code>update</code>" - Attempt to update the database structure to the current mapping (but does not read and invoke
+ * the SQL statements from "import.sql"). <i>Use with caution.</i></li>
+ * <li>"<code>validate</code>" - Validates the existing schema with the current entities configuration, but does not make any
+ * changes to the schema (and does not read and invoke the SQL statements from "import.sql"). This is often the proper setting
+ * to use in production, and thus this is the default value.</li>
+ * </ul>
+ *
+ * @param autoGenerateSchema the setting for the auto-generation, or null if the default should be used
+ */
+ public synchronized void setAutoGenerateSchema( String autoGenerateSchema ) {
+ this.autoGenerateSchema = autoGenerateSchema != null ? autoGenerateSchema.trim() : DEFAULT_AUTO_GENERATE_SCHEMA;
+ }
+
+ /**
* {@inheritDoc}
*
* @see org.jboss.dna.graph.connector.RepositorySource#getRetryLimit()
@@ -758,6 +801,7 @@
ref.add(new StringRefAddr(ENFORCE_REFERENTIAL_INTEGRITY, Boolean.toString(isReferentialIntegrityEnforced())));
ref.add(new StringRefAddr(DEFAULT_WORKSPACE, getDefaultWorkspaceName()));
ref.add(new StringRefAddr(ALLOW_CREATING_WORKSPACES, Boolean.toString(isCreatingWorkspacesAllowed())));
+ ref.add(new StringRefAddr(AUTO_GENERATE_SCHEMA, getAutoGenerateSchema()));
String[] workspaceNames = getPredefinedWorkspaceNames();
if (workspaceNames != null && workspaceNames.length != 0) {
ref.add(new StringRefAddr(PREDEFINED_WORKSPACE_NAMES, StringUtil.combineLines(workspaceNames)));
@@ -811,6 +855,7 @@
String refIntegrity = values.get(ENFORCE_REFERENTIAL_INTEGRITY);
String defaultWorkspace = values.get(DEFAULT_WORKSPACE);
String createWorkspaces = values.get(ALLOW_CREATING_WORKSPACES);
+ String autoGenerateSchema = values.get(AUTO_GENERATE_SCHEMA);
String combinedWorkspaceNames = values.get(PREDEFINED_WORKSPACE_NAMES);
String[] workspaceNames = null;
@@ -845,6 +890,7 @@
if (defaultWorkspace != null) source.setDefaultWorkspaceName(defaultWorkspace);
if (createWorkspaces != null) source.setCreatingWorkspacesAllowed(Boolean.parseBoolean(createWorkspaces));
if (workspaceNames != null && workspaceNames.length != 0) source.setPredefinedWorkspaceNames(workspaceNames);
+ if (autoGenerateSchema != null) source.setAutoGenerateSchema(autoGenerateSchema);
return source;
}
return null;
@@ -1007,7 +1053,7 @@
// setProperty(configuration, "hibernate.show_sql", "true"); // writes all SQL statements to console
setProperty(configuration, "hibernate.format_sql", "true");
setProperty(configuration, "hibernate.use_sql_comments", "true");
- setProperty(configuration, "hibernate.hbm2ddl.auto", "create");
+ setProperty(configuration, "hibernate.hbm2ddl.auto", this.autoGenerateSchema);
}
protected void setProperty( Ejb3Configuration configurator,
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorCreateWorkspacesTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorCreateWorkspacesTest.java 2009-09-03 19:07:26 UTC (rev 1191)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorCreateWorkspacesTest.java 2009-09-03 20:01:08 UTC (rev 1192)
@@ -67,6 +67,7 @@
source.setLargeValueSizeInBytes(150);
source.setCreatingWorkspacesAllowed(true);
source.setPredefinedWorkspaceNames(predefinedWorkspaces);
+ source.setAutoGenerateSchema("create");
return source;
}
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorNoCreateWorkspaceTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorNoCreateWorkspaceTest.java 2009-09-03 19:07:26 UTC (rev 1191)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorNoCreateWorkspaceTest.java 2009-09-03 20:01:08 UTC (rev 1192)
@@ -67,6 +67,7 @@
source.setLargeValueSizeInBytes(150);
source.setCreatingWorkspacesAllowed(false);
source.setPredefinedWorkspaceNames(predefinedWorkspaces);
+ source.setAutoGenerateSchema("create");
return source;
}
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java 2009-09-03 19:07:26 UTC (rev 1191)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorReadingTest.java 2009-09-03 20:01:08 UTC (rev 1192)
@@ -55,6 +55,7 @@
source.setMaximumSizeOfStatementCache(100);
source.setMaximumConnectionIdleTimeInSeconds(0);
source.setLargeValueSizeInBytes(150);
+ source.setAutoGenerateSchema("create");
// Create a graph and look up the root node. We do this to initialize the connection pool and
// force the database to be setup at this point. By doing it now, we don't include this overhead
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorWritingTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorWritingTest.java 2009-09-03 19:07:26 UTC (rev 1191)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaConnectorWritingTest.java 2009-09-03 20:01:08 UTC (rev 1192)
@@ -57,6 +57,7 @@
source.setMaximumConnectionIdleTimeInSeconds(0);
source.setReferentialIntegrityEnforced(true);
source.setLargeValueSizeInBytes(150);
+ source.setAutoGenerateSchema("create");
source.setCompressData(true);
return source;
@@ -93,8 +94,12 @@
graph.create("/newUuids").and();
// Copy once to get the UUID into the default workspace
- //graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/node1");
- graph.clone("/node1").fromWorkspace(workspaceName).as(name("node1")).into("/newUuids").replacingExistingNodesWithSameUuids();
+ // graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/node1");
+ graph.clone("/node1")
+ .fromWorkspace(workspaceName)
+ .as(name("node1"))
+ .into("/newUuids")
+ .replacingExistingNodesWithSameUuids();
// Create a new child node that in the target workspace that has no corresponding node in the source workspace
graph.create("/newUuids/node1/shouldBeRemoved").and();
@@ -106,7 +111,11 @@
// Copy again to test the behavior now that the UUIDs are already in the default workspace
// This should fail because /newUuids/node1/shouldBeRemoved must be removed by the copy, but can't be removed
// because there is a reference to it.
- //graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/otherNode");
- graph.clone("/node1").fromWorkspace(workspaceName).as(name("otherNode")).into("/newUuids").replacingExistingNodesWithSameUuids();
+ // graph.copy("/node1").replacingExistingNodesWithSameUuids().fromWorkspace(workspaceName).to("/newUuids/otherNode");
+ graph.clone("/node1")
+ .fromWorkspace(workspaceName)
+ .as(name("otherNode"))
+ .into("/newUuids")
+ .replacingExistingNodesWithSameUuids();
}
}
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java 2009-09-03 19:07:26 UTC (rev 1191)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java 2009-09-03 20:01:08 UTC (rev 1192)
@@ -60,6 +60,7 @@
this.source.setMaximumConnectionIdleTimeInSeconds(0);
this.source.setDefaultWorkspaceName("default");
this.source.setCreatingWorkspacesAllowed(true);
+ this.source.setAutoGenerateSchema("create");
}
@After
14 years, 8 months
DNA SVN: r1191 - in trunk: dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa and 4 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-09-03 15:07:26 -0400 (Thu, 03 Sep 2009)
New Revision: 1191
Added:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/JcrRepositoryWithJpaConfigurationTest.java
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
Removed:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java
Modified:
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrConfiguration.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
trunk/docs/reference/src/main/docbook/en-US/content/jcr/jcr.xml
Log:
DNA-512 Add simple example (or integration test) that shows all of the code required to use JCR with a JDBC database
Created a new JcrRepositoryWithJpaConfigurationTest in the 'dna-integration-test' project that shows from start to finish how to configure a JBoss DNA JCR repository to use a JDBC database (in this case, HSQLDB).
Also updated the Reference Guide to more clearly document how to use custom security mechanisms.
Deleted: trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java
===================================================================
--- trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java 2009-09-03 16:11:39 UTC (rev 1190)
+++ trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java 2009-09-03 19:07:26 UTC (rev 1191)
@@ -1,123 +0,0 @@
-/*
- * JBoss DNA (http://www.jboss.org/dna)
- * See the COPYRIGHT.txt file distributed with this work for information
- * regarding copyright ownership. Some portions may be licensed
- * to Red Hat, Inc. under one or more contributor license agreements.
- * See the AUTHORS.txt file in the distribution for a full listing of
- * individual contributors.
- *
- * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
- * is licensed to you under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * JBoss DNA is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.dna.test.integration;
-
-import static org.hamcrest.core.Is.is;
-import static org.hamcrest.core.IsNull.notNullValue;
-import static org.junit.Assert.assertThat;
-import javax.jcr.NodeIterator;
-import javax.jcr.Session;
-import org.jboss.dna.connector.svn.SVNRepositorySource;
-import org.jboss.dna.graph.SecurityContext;
-import org.jboss.dna.jcr.JcrConfiguration;
-import org.jboss.dna.jcr.JcrEngine;
-import org.jboss.dna.jcr.SecurityContextCredentials;
-import org.jboss.dna.jcr.JcrRepository.Option;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- *
- */
-public class SvnAndJcrIntegrationTest {
- private JcrEngine engine;
- private Session session;
-
- @Before
- public void beforeEach() throws Exception {
- final String repositoryUrl = "http://anonsvn.jboss.org/repos/dna/";
- final String[] predefinedWorkspaceNames = {repositoryUrl + "trunk", repositoryUrl + "tags", repositoryUrl + "branches"};
- final String svnRepositorySource = "svnRepositorySource";
- final String repositoryName = "svnRepository";
- final JcrConfiguration configuration = new JcrConfiguration();
- configuration.repositorySource(svnRepositorySource)
- .usingClass(SVNRepositorySource.class)
- .setProperty("password", "")
- .setProperty("username", "anonymous")
- .setProperty("repositoryRootURL", repositoryUrl)
- .setProperty("predefinedWorkspaceNames", predefinedWorkspaceNames)
- .setProperty("directoryForDefaultWorkspace", predefinedWorkspaceNames[0])
- .setProperty("creatingWorkspacesAllowed", false);
-
- configuration.repository(repositoryName).setSource(svnRepositorySource).setOption(Option.READ_DEPTH, "1");
- configuration.save();
- this.engine = configuration.build();
- this.engine.start();
-
- this.session = this.engine.getRepository(repositoryName)
- .login(new SecurityContextCredentials(new MyCustomSecurityContext()));
-
- }
-
- @After
- public void afterEach() throws Exception {
- if (this.session != null) {
- this.session.logout();
- }
- if (this.engine != null) {
- this.engine.shutdown();
- }
- }
-
- @Test
- public void shouldIterateOverChildrenOfRoot() throws Exception {
- System.out.println("Getting the root node and it's children ...");
- NodeIterator nodeIterator = this.session.getRootNode().getNodes();
-
- while (nodeIterator.hasNext()) {
- System.out.println(nodeIterator.nextNode());
- }
- assertThat(this.session.getRootNode().getNode("dna-graph"), is(notNullValue()));
- }
-
- protected class MyCustomSecurityContext implements SecurityContext {
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.SecurityContext#getUserName()
- */
- public String getUserName() {
- return "Fred";
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.SecurityContext#hasRole(java.lang.String)
- */
- public boolean hasRole( String roleName ) {
- return true;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.SecurityContext#logout()
- */
- public void logout() {
- // do something
- }
- }
-}
Added: trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/JcrRepositoryWithJpaConfigurationTest.java
===================================================================
--- trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/JcrRepositoryWithJpaConfigurationTest.java (rev 0)
+++ trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/JcrRepositoryWithJpaConfigurationTest.java 2009-09-03 19:07:26 UTC (rev 1191)
@@ -0,0 +1,219 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.test.integration.jpa;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.concurrent.TimeUnit;
+import javax.jcr.Credentials;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import org.jboss.dna.graph.SecurityContext;
+import org.jboss.dna.jcr.JcrConfiguration;
+import org.jboss.dna.jcr.JcrEngine;
+import org.jboss.dna.jcr.JcrRepository;
+import org.jboss.dna.jcr.SecurityContextCredentials;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class JcrRepositoryWithJpaConfigurationTest {
+
+ @Test
+ public void shouldConfigureWithInMemoryDatabase() throws RepositoryException, PrivilegedActionException {
+ configureWithInMemoryDatabase(new CustomSecurityContext("bill"));
+ }
+
+ /**
+ * Test some very basic functionality with an in-memory database and the supplied security context.
+ * <p>
+ * Note that this method is designed to be readable and serve as an example, and therefore there is a certain amount of
+ * repeated code.
+ * </p>
+ *
+ * @param securityContext the security context, or null if JAAS should be used for authentication
+ * @throws RepositoryException if there was an error with the repository
+ * @throws PrivilegedActionException if there was an error executing a privileged action block as the current JAAS subject
+ */
+ protected void configureWithInMemoryDatabase( SecurityContext securityContext )
+ throws RepositoryException, PrivilegedActionException {
+ JcrConfiguration configuration = new JcrConfiguration();
+
+ // Set up the repository source that this JCR repository will use ...
+ configuration.repositorySource("MySource")
+ .setDescription("This is my repository source")
+ .usingClass("org.jboss.dna.connector.store.jpa.JpaSource")
+ .loadedFromClasspath()
+ // The rest of these properties are specific to the JpaSource class.
+
+ // Set up three workspaces that this source will make available,
+ // but for this example allow clients to create more workspaces ...
+ .setProperty("predefinedWorkspaceNames", "workspace1", "workspace2", "workspace3")
+ .setProperty("defaultWorkspaceName", "workspace1")
+ .setProperty("creatingWorkspacesAllowed", true)
+ // Now set the required JDBC properties, since we're using the 'Driver' approach ...
+ .setProperty("dialect", "org.hibernate.dialect.HSQLDialect")
+ .setProperty("driverClassName", "org.hsqldb.jdbcDriver")
+ .setProperty("username", "sa")
+ .setProperty("password", "")
+ .setProperty("url", "jdbc:hsqldb:.")
+ // Alternatively, you could instead point the source to a JDBC DataSource in JNDI ...
+ // .setProperty("dataSourceJndiName","jdbc/TestDB")
+
+ // Set some optional properties ...
+ .setProperty("maximumConnectionsInPool", 3)
+ .setProperty("minimumConnectionsInPool", 0)
+ .setProperty("numberOfConnectionsToAcquireAsNeeded", 1)
+ .setProperty("maximumSizeOfStatementCache", 100)
+ .setProperty("maximumConnectionIdleTimeInSeconds", 0)
+ .setProperty("largeValueSizeInBytes", 150)
+ .setProperty("compressData", true)
+ .setProperty("referentialIntegrityEnforced", true)
+ .setProperty("autoDdl", "create")
+ .setProperty("showSql", false);
+
+ // Set up the JCR repository ...
+ configuration.repository("My JCR Repository")
+ .setDescription("This is the description for my JCR repository (not really accessible through JCR though)")
+ // Tell it which repository source should be used ...
+ .setSource("MySource")
+ // Set the options (all of which have good defaults) ...
+ .setOption(JcrRepository.Option.PROJECT_NODE_TYPES, false)
+ // Load up some node types ...
+ // .addNodeTypes(fileOrUrlOrString)
+ // Register 0 or more namespaces (we'll do an example one here) ...
+ .registerNamespace("myns", "http://www.example.com/some/namespace");
+
+ // Build the JcrEngine from the configuration...
+ JcrEngine engine = configuration.build();
+ try {
+ // First, start the engine ...
+ engine.start();
+
+ // Obtain the JCR Repository ...
+ final Repository myRepository = engine.getRepository("My JCR Repository");
+
+ // Create a session to our JCR repository, but do this for each of the following workspaces
+ // (where 'null' means the default workspace, as defined by our source) ...
+ String[] workspaceNames = {"workspace2", null};
+
+ for (final String workspaceName : workspaceNames) {
+ // Log into the JCR repository ...
+ Session session = null;
+ if (securityContext != null) {
+ // Create a JCR Credentials with our custom security context ...
+ Credentials credentials = new SecurityContextCredentials(securityContext);
+ // And then login ...
+ session = myRepository.login(credentials, workspaceName);
+ } else {
+ // We don't have a custom SecurityContext, so we'll rely upon JAAS for our security.
+ // No need to provide a credentials, so just login with the name of the workspace.
+ // However, we DO need to do this from within a doPrivilege block.
+ session = AccessController.doPrivileged(new PrivilegedExceptionAction<Session>() {
+ public Session run() throws Exception {
+ return myRepository.login(workspaceName);
+ }
+ });
+ }
+ assertThat(session, is(notNullValue()));
+
+ // Now do some not-terribly-interesting stuff ...
+ try {
+ // Get the root node ...
+ Node root = session.getRootNode();
+
+ // Get the "jcr:system" node ...
+ Node jcrSystem = root.getNode("jcr:system");
+ Node namespaces = jcrSystem.getNode("dna:namespaces");
+ assert namespaces != null;
+
+ // Create a few children under the root node, all with the same name (but different SNS indexes) ...
+ for (int i = 0; i != 10; ++i) {
+ root.addNode("childA", "nt:unstructured");
+ }
+
+ // Iterate over the children of the root ...
+ int childCount = 0;
+ for (NodeIterator iter = root.getNodes("child* | nonExistant*"); iter.hasNext();) {
+ Node child = iter.nextNode();
+ assertThat(child.getName(), is("childA"));
+ ++childCount;
+ }
+ assertThat(childCount, is(10));
+
+ } finally {
+ // Always log out of the session ...
+ session.logout();
+ }
+ }
+
+ } catch (PrivilegedActionException e) {
+ // Something went wrong ...
+ throw e;
+ } catch (RepositoryException e) {
+ // Something went wrong ...
+ throw e;
+ } finally {
+ // Shutdown the engine ...
+ engine.shutdown();
+
+ // Wait at most 5 seconds for the shutdown to complete ...
+ try {
+ engine.awaitTermination(5, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ // We were interrupted, but we don't really care.
+ // But since we're eating this exception, we MUST reset the Thread's flag ...
+ Thread.interrupted();
+ }
+ }
+ }
+
+ protected static class CustomSecurityContext implements SecurityContext {
+ private final String username;
+
+ public CustomSecurityContext( String username ) {
+ this.username = username;
+ }
+
+ public String getUserName() {
+ return username;
+ }
+
+ public boolean hasRole( String roleName ) {
+ return true;
+ }
+
+ public void logout() {
+ }
+
+ }
+}
Property changes on: trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/jpa/JcrRepositoryWithJpaConfigurationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Copied: trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java (from rev 1190, trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java)
===================================================================
--- trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java (rev 0)
+++ trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java 2009-09-03 19:07:26 UTC (rev 1191)
@@ -0,0 +1,123 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.test.integration.svn;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+import javax.jcr.NodeIterator;
+import javax.jcr.Session;
+import org.jboss.dna.connector.svn.SVNRepositorySource;
+import org.jboss.dna.graph.SecurityContext;
+import org.jboss.dna.jcr.JcrConfiguration;
+import org.jboss.dna.jcr.JcrEngine;
+import org.jboss.dna.jcr.SecurityContextCredentials;
+import org.jboss.dna.jcr.JcrRepository.Option;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class SvnAndJcrIntegrationTest {
+ private JcrEngine engine;
+ private Session session;
+
+ @Before
+ public void beforeEach() throws Exception {
+ final String repositoryUrl = "http://anonsvn.jboss.org/repos/dna/";
+ final String[] predefinedWorkspaceNames = {repositoryUrl + "trunk", repositoryUrl + "tags", repositoryUrl + "branches"};
+ final String svnRepositorySource = "svnRepositorySource";
+ final String repositoryName = "svnRepository";
+ final JcrConfiguration configuration = new JcrConfiguration();
+ configuration.repositorySource(svnRepositorySource)
+ .usingClass(SVNRepositorySource.class)
+ .setProperty("password", "")
+ .setProperty("username", "anonymous")
+ .setProperty("repositoryRootURL", repositoryUrl)
+ .setProperty("predefinedWorkspaceNames", predefinedWorkspaceNames)
+ .setProperty("directoryForDefaultWorkspace", predefinedWorkspaceNames[0])
+ .setProperty("creatingWorkspacesAllowed", false);
+
+ configuration.repository(repositoryName).setSource(svnRepositorySource).setOption(Option.READ_DEPTH, "1");
+ configuration.save();
+ this.engine = configuration.build();
+ this.engine.start();
+
+ this.session = this.engine.getRepository(repositoryName)
+ .login(new SecurityContextCredentials(new MyCustomSecurityContext()));
+
+ }
+
+ @After
+ public void afterEach() throws Exception {
+ if (this.session != null) {
+ this.session.logout();
+ }
+ if (this.engine != null) {
+ this.engine.shutdown();
+ }
+ }
+
+ @Test
+ public void shouldIterateOverChildrenOfRoot() throws Exception {
+ System.out.println("Getting the root node and it's children ...");
+ NodeIterator nodeIterator = this.session.getRootNode().getNodes();
+
+ while (nodeIterator.hasNext()) {
+ System.out.println(nodeIterator.nextNode());
+ }
+ assertThat(this.session.getRootNode().getNode("dna-graph"), is(notNullValue()));
+ }
+
+ protected class MyCustomSecurityContext implements SecurityContext {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.SecurityContext#getUserName()
+ */
+ public String getUserName() {
+ return "Fred";
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.SecurityContext#hasRole(java.lang.String)
+ */
+ public boolean hasRole( String roleName ) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.SecurityContext#logout()
+ */
+ public void logout() {
+ // do something
+ }
+ }
+}
Property changes on: trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/svn/SvnAndJcrIntegrationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrConfiguration.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrConfiguration.java 2009-09-03 16:11:39 UTC (rev 1190)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrConfiguration.java 2009-09-03 19:07:26 UTC (rev 1191)
@@ -79,7 +79,8 @@
*
* @param <ReturnType>
*/
- public interface RepositoryDefinition<ReturnType> extends Returnable<ReturnType>, Removable<ReturnType> {
+ public interface RepositoryDefinition<ReturnType>
+ extends Returnable<ReturnType>, Removable<ReturnType>, SetDescription<RepositoryDefinition<ReturnType>> {
/**
* Specify the name of the repository source that is to be used by this JCR repository.
@@ -109,6 +110,61 @@
String value );
/**
+ * Specify the repository option that is to be set.
+ *
+ * @param option the option to be set
+ * @param value the new value for the option
+ * @return the interface used to set the value for the property; never null
+ * @throws IllegalArgumentException if either parameter is null
+ */
+ RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
+ boolean value );
+
+ /**
+ * Specify the repository option that is to be set.
+ *
+ * @param option the option to be set
+ * @param value the new value for the option
+ * @return the interface used to set the value for the property; never null
+ * @throws IllegalArgumentException if either parameter is null
+ */
+ RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
+ int value );
+
+ /**
+ * Specify the repository option that is to be set.
+ *
+ * @param option the option to be set
+ * @param value the new value for the option
+ * @return the interface used to set the value for the property; never null
+ * @throws IllegalArgumentException if either parameter is null
+ */
+ RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
+ long value );
+
+ /**
+ * Specify the repository option that is to be set.
+ *
+ * @param option the option to be set
+ * @param value the new value for the option
+ * @return the interface used to set the value for the property; never null
+ * @throws IllegalArgumentException if either parameter is null
+ */
+ RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
+ float value );
+
+ /**
+ * Specify the repository option that is to be set.
+ *
+ * @param option the option to be set
+ * @param value the new value for the option
+ * @return the interface used to set the value for the property; never null
+ * @throws IllegalArgumentException if either parameter is null
+ */
+ RepositoryDefinition<ReturnType> setOption( JcrRepository.Option option,
+ double value );
+
+ /**
* Get the value for the repository option.
*
* @param option the option
@@ -498,6 +554,31 @@
return this;
}
+ public RepositoryDefinition<ReturnType> setOption( Option option,
+ boolean value ) {
+ return setOption(option, Boolean.toString(value));
+ }
+
+ public RepositoryDefinition<ReturnType> setOption( Option option,
+ int value ) {
+ return setOption(option, Integer.toString(value));
+ }
+
+ public RepositoryDefinition<ReturnType> setOption( Option option,
+ long value ) {
+ return setOption(option, Long.toString(value));
+ }
+
+ public RepositoryDefinition<ReturnType> setOption( Option option,
+ float value ) {
+ return setOption(option, Float.toString(value));
+ }
+
+ public RepositoryDefinition<ReturnType> setOption( Option option,
+ double value ) {
+ return setOption(option, Double.toString(value));
+ }
+
public String getOption( Option option ) {
CheckArg.isNotNull(option, "option");
return optionValues.get(option);
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java 2009-09-03 16:11:39 UTC (rev 1190)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaConfiguration.java 2009-09-03 19:07:26 UTC (rev 1191)
@@ -671,6 +671,18 @@
String value );
/**
+ * Set the property value to a string.
+ *
+ * @param beanPropertyName the name of the JavaBean-style property (e.g., "retryLimit")
+ * @param value the first string value for the property
+ * @param additionalValues the additional string values for the property
+ * @return the next component to continue configuration; never null
+ */
+ ReturnType setProperty( String beanPropertyName,
+ String value,
+ String... additionalValues );
+
+ /**
* Set the property value to an object.
*
* @param beanPropertyName the name of the JavaBean-style property (e.g., "retryLimit")
@@ -1104,6 +1116,15 @@
return setProperty(beanPropertyName, (Object)value);
}
+ public ThisType setProperty( String beanPropertyName,
+ String firstValue,
+ String... additionalValues ) {
+ Object[] values = new Object[1 + additionalValues.length];
+ values[0] = firstValue;
+ System.arraycopy(additionalValues, 0, values, 1, additionalValues.length);
+ return setProperty(beanPropertyName, values);
+ }
+
public Property getProperty( String beanPropertyName ) {
return properties.get(context.getValueFactories().getNameFactory().create(beanPropertyName));
}
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java 2009-09-03 16:11:39 UTC (rev 1190)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java 2009-09-03 19:07:26 UTC (rev 1191)
@@ -420,6 +420,9 @@
}
return false;
} catch (Exception e) {
+ // Log that the property was not found ...
+ Logger.getLogger(getClass())
+ .debug("Unknown property '{0}' on '{1}' class", propertyName, target.getClass().getName());
return false;
}
}
Modified: trunk/docs/reference/src/main/docbook/en-US/content/jcr/jcr.xml
===================================================================
--- trunk/docs/reference/src/main/docbook/en-US/content/jcr/jcr.xml 2009-09-03 16:11:39 UTC (rev 1190)
+++ trunk/docs/reference/src/main/docbook/en-US/content/jcr/jcr.xml 2009-09-03 19:07:26 UTC (rev 1191)
@@ -65,23 +65,36 @@
<sect1 id="jcr-sessions">
<title>Creating JCR Sessions</title>
<para>Once you have obtained a reference to the JCR &Repository;, you can create a JCR session using one of its
- <code>login(...)</code> methods. The <ulink url="&JSR170;">JSR-170</ulink> specification provides four login methods.
+ <code>login(...)</code> methods. The <ulink url="&JSR170;">JSR-170</ulink> specification provides four login methods, but the
+ behavior of these methods depends on the kind of authentication system your application is using.
</para>
- <para>The first method allows the implementation to choose its own security context to create a session in the default workspace
- for the repository. The JBoss DNA JCR implementation uses the security context from the current &AccessControlContext;. This implies
+ <sect2 id="jcr-sessions-jaas">
+ <title>Using JAAS</title>
+ <para>The <code>login()</code> method allows the implementation to choose its own security context to create a session in the default workspace
+ for the repository. The JBoss DNA JCR implementation uses the security context from the current JAAS &AccessControlContext;. This implies
that this method will throw a &LoginException; if it is not executed as a &PrivilegedAction;. Here is one example of how this might
work:
<programlisting>
Subject subject = ...;
-&Session; session = (&Session;) Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<&Session;>() {
+&Session; session = Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<&Session;>() {
public Session run() throws Exception {
return repository.login();
}
}, AccessController.getContext());
</programlisting>
- This approach will yield a session with the same user name and roles as <code>subject</code>. There is a comparable
- version of <code>login(...)</code> that allows the workspace to be specified by name.
+ Another variant of this is to use the AccessControlContext directly, which then operates against the current Subject:
<programlisting>
+&Session; session = AccessController.doPrivileged( new PrivilegedExceptionAction<&Session;>() {
+ public Session run() throws Exception {
+ return repository.login();
+ }
+});
+</programlisting>
+ </para>
+ <para>
+ Either of these approaches will yield a session with the same user name and roles as <code>subject</code>. The <code>login(String workspaceName)</code>
+ method is comparable and allows the workspace to be specified by name:
+ <programlisting>
Subject subject = ...;
final &String; workspaceName = ...;
&Session; session = (&Session;) Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<&Session;>() {
@@ -90,16 +103,16 @@
}}, AccessController.getContext());
</programlisting>
</para>
- <para>It is also possible to supply the &Credentials; directly as part of the login process, although JBoss DNA imposes
- some requirements on what types of &Credentials; may be supplied. The simplest way is to provide a &SimpleCredentials; object.
- These credentials will be validated against the JAAS realm named "dna-jcr" unless another realm name is provided as an option
+ <para>The JCR API also allows supplying a JCR &Credentials; object directly as part of the login process, although JBoss DNA imposes
+ some requirements on what types of &Credentials; may be supplied. The simplest way is to provide a JCR &SimpleCredentials; object.
+ These credentials will be validated against the JAAS realm named "dna-jcr", unless another realm name is provided as an option
during the JCR repository configuration. For example:
<programlisting>
&String; userName = ...;
char[] password = ...;
&Session; session = repository.login(new &SimpleCredentials;(userName, password));
</programlisting>
- The credentials-based <code>login(...)</code> method also supports an optional workspace name.
+ Similarly, the <code>login(Credentials credentials, String workspaceName)</code> method enables passing the credentials and a workspace name:
<programlisting>
&String; userName = ...;
char[] password = ...;
@@ -116,19 +129,47 @@
return loginContext;
}
}, workspaceName);
-</programlisting>
- Servlet-based applications may wish to reuse the authentication information from &HttpServletRequest; instead. Please note that
+</programlisting>
+ </para>
+ </sect2>
+ <sect2 id="jcr-sessions-custom">
+ <title>Using Custom security</title>
+ <para>
+ Not all applications can or want to use JAAS for their authentication system, so JBoss DNA provides a way to integrate your own custom
+ security provider. The first step is to provide a custom implementation of &SecurityContext; that integrates with your application security, allowing
+ JBoss DNA to discover the authenticated user's name, determine whether the authenticated user has been assigned particular roles
+ (see the <ulink linkend="dna_jcr_security">JCR Security section</ulink>), and to notify your application security system that the
+ authenticated session (for JCR) has ended.
+ </para>
+ <para>
+ The next step is to wrap your &SecurityContext; instance within an instance of &SecurityContextCredentials;, and pass it as the Credentials
+ parameter in one of the two <code>login(...)</code> methods:
+ <programlisting>
+&SecurityContext; securityContext = new CustomSecurityContext(...);
+&Session; session = repository.login(new &SecurityContextCredentials;(securityContext));
+ </programlisting>
+ Once the &Session; is obtained, the repository content can be accessed and modified like any other JCR repository.
+ </para>
+ <para>
+ At this time, no roles are required to connect to any workspace, but restrictions on workspace connections will likely be added to JBoss DNA in the near future.
+ Please see the <ulink linkend="dna_jcr_security">JCR Security section</ulink> for more details on how access is controlled.
+ </para>
+ </sect2>
+ <sect2 id="jcr-sessions-servlet">
+ <title>Using HTTP Servlet security</title>
+ <para>
+ Servlet-based applications can make use of the servlet's existing authentication mechanism from &HttpServletRequest;. Please note that
the example below assumes that the servlet has a security constraint that prevents unauthenticated access.
<programlisting>
&HttpServletRequest; request = ...;
-&ServletSecurityContext; securityContext = new ServletSecurityContext(request);
-&Session; session = repository.login(new &SecurityContextCredentials;(securityContext);
-</programlisting>
- Once the &Session; is obtained, the repository content can be accessed and modified like any other JCR repository. No roles are required to connect
- to any workspace at this time. Restrictions on workspace connections will likely be added to JBoss DNA in the near future. The roles from the JAAS
- information or the &HttpServletRequest; are used to control read and write access to the repository. Please see the <ulink linkend="dna_jcr_security">JCR Security section</ulink>
- for more details on how access is controlled.
+&SecurityContext; securityContext = new &ServletSecurityContext;(request);
+&Session; session = repository.login(new &SecurityContextCredentials;(securityContext));
+</programlisting>
+ You'll note that this is just a specialization of the <ulink linkend="jcr-sessions-custom">custom security context</ulink> approach, since
+ the &ServletSecurityContext; just implements the &SecurityContext; interface and delegates to the &HttpServletRequest;. Feel free to use
+ this class in your servlet-based applications.
</para>
+ </sect2>
</sect1>
<sect1>
<title>JCR Specification Support</title>
14 years, 8 months
DNA SVN: r1190 - in trunk: dna-graph/src/main/java/org/jboss/dna/graph/connector/federation and 16 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-09-03 12:11:39 -0400 (Thu, 03 Sep 2009)
New Revision: 1190
Added:
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/RepositorySource.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/FederatedRepositorySource.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/TimeDelayingRepositorySource.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/AbstractConnectorTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/CndNodeTypeRegistrationTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSessionTest.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/TypeRegistrationTest.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryLibrary.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/FakeRepositorySource.java
trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencer/StreamSequencerAdapterTest.java
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositorySource.java
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemSource.java
trunk/extensions/dna-connector-infinispan/src/main/java/org/jboss/dna/connector/infinispan/InfinispanSource.java
trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
trunk/extensions/dna-connector-jdbc-metadata/src/main/java/org/jboss/dna/connector/jdbc/JdbcRepositorySource.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaConnection.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaConnectorI18n.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java
trunk/extensions/dna-connector-store-jpa/src/main/resources/org/jboss/dna/connector/store/jpa/JpaConnectorI18n.properties
trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java
trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositorySource.java
Log:
DNA-509 JPA Connector does not close all EntityManager instances that it creates
Added to the JPA Connector project a new class that allows JpaSource and JpaConnection to hold onto a JPA EntityManager and EntityManagerFactory, while ensuring that the EntityManager and EntityManagerFactory instances are ALWAYS closed - as long as the JpaConnection objects and JpaSource objects are always closed (in any order). It also allows the JpaSource to start using a new EntityManagerFactory if the settings are changed, without impacting any previously-opened and in-use connections.
Although I did try to find a way for the JpaSource to not have a 'close()' method, it simply was not possible to do without adding TREMENDOUS overhead to the creation of an EntityManagerFactory for every connection (remember, the EntityManagerFactory must be configured with each entity class, and does the schema validation/create/drop/update operations, and this had to be done on EVERY create new connection). And rather than have 'close()' be an artifact of the JpaSource class, it's actually better if this method is defined on the RepositorySource interface and that all implementations provide a close() method. This provides a standard way for the RepositorySource implementations to begin reclaiming resources such as connections, caches, files, and/or large objects. RepositoryLibrary and RepositoryService were modified to ensure that all RepositorySource objects are closed when the library and service are shutdown (via their administrative interface).
The reusable connector framework unit tests were also modified to ensure that they all close the RepositorySource upon teardown of the tests (or, in the case of the reading tests, upon teardown after all tests are run).
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/RepositorySource.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/RepositorySource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/RepositorySource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -193,4 +193,20 @@
*/
RepositorySourceCapabilities getCapabilities();
+ /**
+ * Signal this source that it is no longer needed and should begin the process of reclaiming or closing all resources that it
+ * has acquired. Because {@link #getConnection() connections} may still be in use, this method may not necessarily close all
+ * resources immediately.
+ * <p>
+ * This is a required method, and must be called when this source is no longer needed if one or more {@link #getConnection()
+ * connections} have been obtained since the previous call to this method.
+ * </p>
+ * <p>
+ * Note that calling this method also does not preclude {@link #getConnection() obtaining more connections} after this method
+ * is called. If that happens, this source should simply reacquire any resources necessary to provide additional connections,
+ * and this method needs to be called once again.
+ * </p>
+ */
+ void close();
+
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/FederatedRepositorySource.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/FederatedRepositorySource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/FederatedRepositorySource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -191,6 +191,18 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public void close() {
+ synchronized (this) {
+ // Release the configuration ...
+ this.configuration = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see javax.naming.Referenceable#getReference()
*/
public Reference getReference() {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/inmemory/InMemoryRepositorySource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -256,7 +256,7 @@
*
* @see org.jboss.dna.graph.connector.RepositorySource#getConnection()
*/
- public RepositoryConnection getConnection() throws RepositorySourceException {
+ public synchronized RepositoryConnection getConnection() throws RepositorySourceException {
if (repository == null) {
repository = new InMemoryRepository(name, rootNodeUuid, defaultWorkspaceName);
}
@@ -265,7 +265,17 @@
/**
* {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
*/
+ public synchronized void close() {
+ // Null the reference to the in-memory repository; open connections still reference it and can continue to work ...
+ this.repository = null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public synchronized Reference getReference() {
String className = getClass().getName();
String factoryClassName = this.getClass().getName();
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/TimeDelayingRepositorySource.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/TimeDelayingRepositorySource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/TimeDelayingRepositorySource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -182,6 +182,15 @@
}
/**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public void close() {
+ // Do not do anything, since when the connections are closed they'll be removed from the 'openConnections' set
+ }
+
+ /**
* Factory method that can be overridden by subclasses. This method implementation simply creates a mock {@link XAResource}.
*
* @param connectionName the name of the connection
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/AbstractConnectorTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/AbstractConnectorTest.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/AbstractConnectorTest.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -28,7 +28,6 @@
import static org.junit.Assert.assertThat;
import java.io.PrintStream;
import java.io.PrintWriter;
-import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -39,7 +38,6 @@
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.jboss.dna.common.statistic.Stopwatch;
-import org.jboss.dna.common.util.Reflection;
import org.jboss.dna.graph.DnaLexicon;
import org.jboss.dna.graph.ExecutionContext;
import org.jboss.dna.graph.Graph;
@@ -170,13 +168,9 @@
}
}
if (source != null) {
+ // Close the source, notifying it that it can reclaim any resources ...
try {
- Reflection reflection = new Reflection(source.getClass());
- reflection.invokeBestMethodOnTarget(new String[] {"close"}, source);
- } catch (NoSuchMethodException err) {
- // do nothing (method did not exist)
- } catch (IllegalAccessException err) {
- } catch (InvocationTargetException err) {
+ source.close();
} finally {
source = null;
}
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/CndNodeTypeRegistrationTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/CndNodeTypeRegistrationTest.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/CndNodeTypeRegistrationTest.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -70,11 +70,6 @@
}
- @Test( expected = AssertionError.class )
- public void shouldNotAllowNullTypeSource() throws Exception {
- repoTypeManager.registerNodeTypes((JcrNodeTypeSource)null);
- }
-
@Test( expected = RepositoryException.class )
public void shouldNotAllowRedefinitionOfExistingType() throws Exception {
nodeTypes = new CndNodeTypeSource(CND_LOCATION + "existingType.cnd");
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSessionTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSessionTest.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrSessionTest.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -98,26 +98,6 @@
}
}
- @Test( expected = AssertionError.class )
- public void shouldNotAllowNullRepository() throws Exception {
- new JcrSession(null, workspace, context, sessionAttributes);
- }
-
- @Test( expected = AssertionError.class )
- public void shouldNotAllowNullWorkspace() throws Exception {
- new JcrSession(repository, null, context, sessionAttributes);
- }
-
- @Test( expected = AssertionError.class )
- public void shouldNotAllowNullExecutionContext() throws Exception {
- new JcrSession(repository, workspace, null, sessionAttributes);
- }
-
- @Test( expected = AssertionError.class )
- public void shouldNotAllowNullSessionAttributesMap() throws Exception {
- new JcrSession(repository, workspace, context, null);
- }
-
@Test( expected = UnsupportedOperationException.class )
public void shouldNotAllowAddLockToken() throws Exception {
session.addLockToken(null);
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/TypeRegistrationTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/TypeRegistrationTest.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/TypeRegistrationTest.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -66,16 +66,6 @@
nameFactory = context.getValueFactories().getNameFactory();
}
- @Test( expected = AssertionError.class )
- public void shouldNotAllowNullDefinition() throws Exception {
- repoTypeManager.registerNodeType(null, true);
- }
-
- @Test( expected = AssertionError.class )
- public void shouldNotAllowTemplateWithNullContext() throws Exception {
- repoTypeManager.registerNodeType(new JcrNodeTypeTemplate(null), true);
- }
-
@Test( expected = InvalidNodeTypeDefinitionException.class )
public void shouldNotAllowNodeTypeWithNoName() throws Exception {
ntTemplate.setName(null);
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryLibrary.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryLibrary.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryLibrary.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -218,7 +218,10 @@
try {
this.sourcesLock.readLock().lock();
for (RepositoryConnectionPool pool : this.pools.values()) {
+ // Shutdown the pool of connections ...
pool.shutdown();
+ // Now close the source (still allows in-use connections to be used) ...
+ pool.getRepositorySource().close();
}
} finally {
this.sourcesLock.readLock().unlock();
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -94,6 +94,17 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.repository.service.AbstractServiceAdministrator#doShutdown(org.jboss.dna.repository.service.ServiceAdministrator.State)
+ */
+ @Override
+ protected void doShutdown( State fromState ) {
+ super.doShutdown(fromState);
+ shutdownService();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.repository.service.ServiceAdministrator#awaitTermination(long, java.util.concurrent.TimeUnit)
*/
public boolean awaitTermination( long timeout,
@@ -228,6 +239,11 @@
}
}
+ protected synchronized void shutdownService() {
+ // Close the repository library ...
+ this.sources.getAdministrator().shutdown();
+ }
+
/**
* Instantiate the {@link RepositorySource} described by the supplied properties.
*
Modified: trunk/dna-repository/src/test/java/org/jboss/dna/repository/FakeRepositorySource.java
===================================================================
--- trunk/dna-repository/src/test/java/org/jboss/dna/repository/FakeRepositorySource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-repository/src/test/java/org/jboss/dna/repository/FakeRepositorySource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -79,6 +79,15 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public void close() {
+ // do nothing
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.connector.RepositorySource#getName()
*/
public String getName() {
Modified: trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencer/StreamSequencerAdapterTest.java
===================================================================
--- trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencer/StreamSequencerAdapterTest.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/dna-repository/src/test/java/org/jboss/dna/repository/sequencer/StreamSequencerAdapterTest.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -70,7 +70,7 @@
private StreamSequencerAdapter sequencer;
private final String[] validExpressions = {"/a/* => /output"};
private final SequencerConfig validConfig = new SequencerConfig("name", "desc", Collections.<String, Object>emptyMap(),
- "something.class", null, validExpressions);
+ "something.class", null, validExpressions);
private SequencerOutputMap sequencerOutput;
private final String sampleData = "The little brown fox didn't something bad.";
private ExecutionContext context;
@@ -422,28 +422,6 @@
});
}
- @Test( expected = java.lang.AssertionError.class )
- public void shouldNotAllowNullInputNode() throws Exception {
- sequencer.createStreamSequencerContext(null, sequencedProperty, seqContext, problems);
- }
-
- @Test( expected = java.lang.AssertionError.class )
- public void shouldNotAllowNullSequencedProperty() throws Exception {
-
- graph.create("/a").and();
- Node input = graph.getNodeAt("/a");
- sequencer.createStreamSequencerContext(input, null, seqContext, problems);
- }
-
- @Test( expected = java.lang.AssertionError.class )
- public void shouldNotAllowNullExecutionContext() throws Exception {
-
- this.sequencedProperty = mock(Property.class);
- graph.create("/a").and();
- Node input = graph.getNodeAt("/a");
- sequencer.createStreamSequencerContext(input, sequencedProperty, null, problems);
- }
-
@Test
public void shouldProvideNamespaceRegistry() throws Exception {
Modified: trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositorySource.java
===================================================================
--- trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositorySource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatedRepositorySource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -467,6 +467,15 @@
}
/**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public void close() {
+ // do nothing ...
+ }
+
+ /**
* Get the {@link FederatedRepository} instance that this source is using. This method uses the following logic:
* <ol>
* <li>If a {@link FederatedRepository} already was obtained from a prior call, the same instance is returned.</li>
Modified: trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemSource.java
===================================================================
--- trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemSource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemSource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -563,12 +563,21 @@
}
};
}
-
+
return new FileSystemConnection(name, defaultWorkspaceName, availableWorkspaces, isCreatingWorkspacesAllowed(),
cachePolicy, rootNodeUuid, workspaceRootPath, maxPathLength, filenameFilter,
getSupportsUpdates());
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public synchronized void close() {
+ this.availableWorkspaces = null;
+ }
+
@Immutable
/*package*/class FileSystemCachePolicy implements CachePolicy {
private static final long serialVersionUID = 1L;
Modified: trunk/extensions/dna-connector-infinispan/src/main/java/org/jboss/dna/connector/infinispan/InfinispanSource.java
===================================================================
--- trunk/extensions/dna-connector-infinispan/src/main/java/org/jboss/dna/connector/infinispan/InfinispanSource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-infinispan/src/main/java/org/jboss/dna/connector/infinispan/InfinispanSource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -420,6 +420,16 @@
}
/**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public synchronized void close() {
+ // Null the reference to the repository; open connections still reference it and can continue to work ...
+ this.repository = null;
+ }
+
+ /**
* @return repositoryContext
*/
public RepositoryContext getRepositoryContext() {
@@ -430,7 +440,7 @@
return repositoryContext != null ? repositoryContext.getObserver() : null;
}
- protected Context getContext() {
+ protected synchronized Context getContext() {
return this.jndiContext;
}
Modified: trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java
===================================================================
--- trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-jbosscache/src/main/java/org/jboss/dna/connector/jbosscache/JBossCacheSource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -485,6 +485,16 @@
}
/**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public synchronized void close() {
+ // Null the reference to the repository; open connections still reference it and can continue to work ...
+ this.repository = null;
+ }
+
+ /**
* Method that is responsible for attempting to create a new cache given the supplied workspace name. Note that this is
* probably called at most once for each workspace name (except if this method fails to create a cache for a given workspace
* name).
Modified: trunk/extensions/dna-connector-jdbc-metadata/src/main/java/org/jboss/dna/connector/jdbc/JdbcRepositorySource.java
===================================================================
--- trunk/extensions/dna-connector-jdbc-metadata/src/main/java/org/jboss/dna/connector/jdbc/JdbcRepositorySource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-jdbc-metadata/src/main/java/org/jboss/dna/connector/jdbc/JdbcRepositorySource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -42,7 +42,6 @@
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
-
import net.jcip.annotations.ThreadSafe;
import org.jboss.dna.common.i18n.I18n;
import org.jboss.dna.common.jdbc.provider.DataSourceDatabaseMetadataProvider;
@@ -96,7 +95,7 @@
protected transient DriverDatabaseMetadataProvider driverProvider;
protected transient DataSourceDatabaseMetadataProvider dataSourceProvider;
protected transient UUID rootUuid = UUID.fromString(DEFAULT_ROOT_NODE_UUID);
-
+
protected static final String SOURCE_NAME = "sourceName";
protected static final String ROOT_NODE_UUID = "rootNodeUuid";
protected static final String DEFAULT_CACHE_POLICY = "defaultCachePolicy";
@@ -108,11 +107,12 @@
protected static final String RETRY_LIMIT = "retryLimit";
/**
- * Get and optionally create driver based provider
+ * Get and optionally create driver based provider
+ *
* @param create create provider
* @return driverProvider
*/
- protected DriverDatabaseMetadataProvider getDriverProvider(boolean create) {
+ protected DriverDatabaseMetadataProvider getDriverProvider( boolean create ) {
// lazy creation
if (driverProvider == null) {
driverProvider = new DefaultDriverDatabaseMetadataProvider();
@@ -121,18 +121,19 @@
}
/**
- * Get and optionally create data source based provider
+ * Get and optionally create data source based provider
+ *
* @param create create provider
* @return dataSourceProvider
*/
- protected DataSourceDatabaseMetadataProvider getDataSourceProvider(boolean create) {
+ protected DataSourceDatabaseMetadataProvider getDataSourceProvider( boolean create ) {
// lazy creation
if (dataSourceProvider == null && create) {
dataSourceProvider = new DefaultDataSourceDatabaseMetadataProvider();
}
return dataSourceProvider;
}
-
+
/**
* default constructor
*/
@@ -153,22 +154,19 @@
*
* @see org.jboss.dna.graph.connector.RepositorySource#getConnection()
*/
- public RepositoryConnection getConnection() throws RepositorySourceException {
+ public synchronized RepositoryConnection getConnection() throws RepositorySourceException {
String errMsg = null;
// check name
if (getName() == null) {
errMsg = JdbcMetadataI18n.propertyIsRequired.text("name");
throw new RepositorySourceException(errMsg);
}
-
+
// create Jdbc connection using data source first
try {
if (dataSourceProvider != null) {
// create wrapper for Jdbc connection
- return new JdbcConnection(getName(),
- getDefaultCachePolicy(),
- dataSourceProvider.getConnection(),
- rootUuid);
+ return new JdbcConnection(getName(), getDefaultCachePolicy(), dataSourceProvider.getConnection(), rootUuid);
}
} catch (Exception e) {
errMsg = JdbcMetadataI18n.unableToGetConnectionUsingDriver.text(getName(), getDriverClassName(), getDatabaseUrl());
@@ -179,16 +177,13 @@
try {
if (driverProvider != null) {
// create wrapper for Jdbc connection
- return new JdbcConnection(getName(),
- getDefaultCachePolicy(),
- driverProvider.getConnection(),
- rootUuid);
+ return new JdbcConnection(getName(), getDefaultCachePolicy(), driverProvider.getConnection(), rootUuid);
}
} catch (Exception e) {
errMsg = JdbcMetadataI18n.unableToGetConnectionUsingDataSource.text(getName(), getDataSourceName());
throw new RepositorySourceException(errMsg, e);
}
-
+
// Either data source name or JDBC driver connection properties must be defined
errMsg = JdbcMetadataI18n.oneOfPropertiesIsRequired.text(getName());
throw new RepositorySourceException(errMsg);
@@ -197,6 +192,14 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public synchronized void close() {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.connector.RepositorySource#getName()
*/
public String getName() {
@@ -278,7 +281,7 @@
* @return rootNodeUuid
*/
public String getRootNodeUuid() {
- return rootUuid != null? rootUuid.toString() : null;
+ return rootUuid != null ? rootUuid.toString() : null;
}
/**
@@ -289,7 +292,7 @@
if (rootNodeUuid != null && rootNodeUuid.trim().length() == 0) rootNodeUuid = DEFAULT_ROOT_NODE_UUID;
this.rootUuid = UUID.fromString(rootNodeUuid);
}
-
+
/**
* {@inheritDoc}
*/
@@ -316,10 +319,10 @@
public String getDriverClassName() {
// get provider
DriverDatabaseMetadataProvider provider = getDriverProvider(false);
- // return
- return (provider != null)? provider.getDriverClassName() : null;
+ // return
+ return (provider != null) ? provider.getDriverClassName() : null;
}
-
+
/**
* Sets JDBC driver class name
*
@@ -335,7 +338,7 @@
provider.setDriverClassName(driverClassName);
}
}
-
+
/**
* Gets database URL as string
*
@@ -344,8 +347,8 @@
public String getDatabaseUrl() {
// get provider
DriverDatabaseMetadataProvider provider = getDriverProvider(false);
- // return
- return (provider != null)? provider.getDatabaseUrl() : null;
+ // return
+ return (provider != null) ? provider.getDatabaseUrl() : null;
}
/**
@@ -363,7 +366,7 @@
provider.setDatabaseUrl(databaseUrl);
}
}
-
+
/**
* Gets the user name
*
@@ -372,7 +375,7 @@
public String getUserName() {
// get provider
DriverDatabaseMetadataProvider provider = getDriverProvider(false);
- return (provider != null)? provider.getUserName() : null;
+ return (provider != null) ? provider.getUserName() : null;
}
/**
@@ -389,7 +392,7 @@
provider.setUserName(userName);
}
}
-
+
/**
* Get user's password
*
@@ -398,8 +401,8 @@
public String getPassword() {
// get provider
DriverDatabaseMetadataProvider provider = getDriverProvider(false);
- return (provider != null)? provider.getPassword() : null;
- }
+ return (provider != null) ? provider.getPassword() : null;
+ }
/**
* Sets the user's password
@@ -415,7 +418,7 @@
provider.setPassword(password);
}
}
-
+
/**
* Sets data source JNDI name
*
@@ -424,7 +427,7 @@
public String getDataSourceName() {
// get provider
DataSourceDatabaseMetadataProvider provider = getDataSourceProvider(false);
- return (provider != null)? provider.getDataSourceName() : null;
+ return (provider != null) ? provider.getDataSourceName() : null;
}
/**
@@ -441,7 +444,7 @@
provider.setDataSourceName(dataSourceName);
}
}
-
+
/**
* {@inheritDoc}
*
@@ -455,29 +458,29 @@
if (getName() != null) {
ref.add(new StringRefAddr(SOURCE_NAME, getName()));
}
-
+
if (getRootNodeUuid() != null) {
ref.add(new StringRefAddr(ROOT_NODE_UUID, getRootNodeUuid()));
}
if (getDataSourceName() != null) {
ref.add(new StringRefAddr(DATA_SOURCE_JNDI_NAME, getDataSourceName()));
}
-
+
if (getUserName() != null) {
ref.add(new StringRefAddr(USERNAME, getUserName()));
}
-
+
if (getPassword() != null) {
ref.add(new StringRefAddr(PASSWORD, getPassword()));
}
-
+
if (getDatabaseUrl() != null) {
ref.add(new StringRefAddr(URL, getDatabaseUrl()));
}
if (getDriverClassName() != null) {
ref.add(new StringRefAddr(DRIVER_CLASS_NAME, getDriverClassName()));
}
-
+
if (getDefaultCachePolicy() != null) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
CachePolicy policy = getDefaultCachePolicy();
@@ -535,7 +538,7 @@
String password = (String)values.get(PASSWORD);
String url = (String)values.get(URL);
String driverClassName = (String)values.get(DRIVER_CLASS_NAME);
-
+
Object defaultCachePolicy = values.get(DEFAULT_CACHE_POLICY);
String retryLimit = (String)values.get(RETRY_LIMIT);
Added: trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java (rev 0)
+++ trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -0,0 +1,151 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.connector.store.jpa;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import net.jcip.annotations.ThreadSafe;
+import org.hibernate.ejb.Ejb3Configuration;
+
+/**
+ * Utility class that owns an {@link EntityManagerFactory} instance and that provides references to {@link EntityManager}
+ * instances while providing the ability to properly clean up all resources by closing the EntityManager and EntityManagerFactory
+ * objects when no longer needed.
+ * <p>
+ * This class is instantiated by the {@link JpaSource} and passed to the {@link JpaConnection} objects, which use this class to
+ * obtain an EntityManager. When the JpaConnection object is {@link JpaConnection#close() closed}, it returns the EntityManager to
+ * this object. Because this class maintains a count of the EntityManager references handed out, the last EntityManager to be
+ * returned will cause the EntityManagerFactory to be closed.
+ * </p>
+ * <p>
+ * This class does put the EntityManager implementations inside a HashMap, and therefore does expect that the EntityManager uses
+ * object equality for <code>equals</code>.
+ * </p>
+ */
+@ThreadSafe
+class EntityManagers {
+
+ private final Ejb3Configuration configuration;
+ private final Map<EntityManager, AtomicInteger> referenceCounts = new HashMap<EntityManager, AtomicInteger>();
+ private EntityManagerFactory factory;
+ private boolean canClose;
+
+ EntityManagers( Ejb3Configuration configuration ) {
+ this.configuration = configuration;
+ }
+
+ /**
+ * Check out an EntityManager instance. The resulting manager <i>must</i> be returned with {@link #checkin(EntityManager)}. In
+ * fact, for every {@link #checkout()} call, there must be a corresponding {@link #checkin(EntityManager)} call with the
+ * checked out EntityManager.
+ * <p>
+ * Note that this class may return the same EntityManager for multiple calls, but this should not matter to the caller.
+ * </p>
+ *
+ * @return the entity manager; never null
+ */
+ public synchronized EntityManager checkout() {
+ if (factory == null) {
+ // Create the factory ...
+ factory = configuration.buildEntityManagerFactory();
+ assert referenceCounts.isEmpty();
+ canClose = false;
+ }
+ // Create the entity manager and increment the reference count ...
+ EntityManager manager = factory.createEntityManager();
+ if (referenceCounts.containsKey(manager)) {
+ referenceCounts.get(manager).incrementAndGet();
+ } else {
+ referenceCounts.put(manager, new AtomicInteger(1));
+ }
+ return manager;
+ }
+
+ /**
+ * Return an EntityManager when it is no longer needed. This method should be called once supplying the same EntityManager
+ * instance returned from a {@link #checkout()} call. In fact, for every {@link #checkout()} call, there must be a
+ * corresponding {@link #checkin(EntityManager)} call with the checked out EntityManager.
+ * <p>
+ * If this is the last reference to the EntityManager instance, it will be closed.
+ * </p>
+ *
+ * @param manager the entity manager; may not be null and must be the result of a prior {@link #checkout()} call
+ */
+ public synchronized void checkin( EntityManager manager ) {
+ if (manager == null) return;
+ // Decrement the reference count ...
+ AtomicInteger count = referenceCounts.get(manager);
+ assert count != null;
+ count.decrementAndGet();
+ assert count.get() >= 0;
+ if (count.get() == 0) {
+ // Need to remove this manager ...
+ if (referenceCounts.remove(manager) != null) {
+ // And close the manager ...
+ manager.close();
+ }
+ }
+ // If there are no more entity managers checkout out, close the factory ...
+ closeFactoryIfNoManagersCheckedOut();
+ }
+
+ public synchronized void close() {
+ canClose = true;
+ closeFactoryIfNoManagersCheckedOut();
+ }
+
+ /**
+ * For all opened EntityManager instances to be closed immediately, even if they are checked out. This should be called with
+ * caution, since all EntityManager and EntityManagerFactory instances will be closed when no longer used - as long as the
+ * {@link #checkout() checkout}/{@link #checkin(EntityManager) checkin} pattern is always used.
+ */
+ public synchronized void closeNow() {
+ canClose = true;
+ try {
+ for (EntityManager manager : referenceCounts.keySet()) {
+ manager.close();
+ }
+ referenceCounts.clear();
+ } finally {
+ try {
+ factory.close(); // This implicitly closes all EntityManagers that are still opened
+ } finally {
+ factory = null;
+ }
+ }
+ }
+
+ private void closeFactoryIfNoManagersCheckedOut() {
+ if (referenceCounts.isEmpty() && canClose) {
+ try {
+ factory.close();
+ } finally {
+ factory = null;
+ }
+ }
+ }
+}
Property changes on: trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/EntityManagers.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaConnection.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaConnection.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaConnection.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -42,7 +42,8 @@
private final String name;
private final CachePolicy cachePolicy;
- private final EntityManager entityManager;
+ private final EntityManagers entityManagers;
+ private EntityManager entityManager;
private final Model model;
private final UUID rootNodeUuid;
private final String nameOfDefaultWorkspace;
@@ -56,7 +57,7 @@
/*package*/JpaConnection( String sourceName,
Observer observer,
CachePolicy cachePolicy,
- EntityManager entityManager,
+ EntityManagers entityManagers,
Model model,
UUID rootNodeUuid,
String nameOfDefaultWorkspace,
@@ -66,13 +67,15 @@
boolean compressData,
boolean enforceReferentialIntegrity ) {
assert sourceName != null;
- assert entityManager != null;
+ assert entityManagers != null;
assert model != null;
assert rootNodeUuid != null;
this.observer = observer;
this.name = sourceName;
this.cachePolicy = cachePolicy; // may be null
- this.entityManager = entityManager;
+ this.entityManagers = entityManagers;
+ this.entityManager = entityManagers.checkout();
+ assert this.entityManagers != null;
this.model = model;
this.rootNodeUuid = rootNodeUuid;
this.largeValueMinimumSizeInBytes = largeValueMinimumSizeInBytes;
@@ -117,7 +120,7 @@
*/
public boolean ping( long time,
TimeUnit unit ) {
- return entityManager.isOpen();
+ return entityManager != null ? entityManager.isOpen() : false;
}
/**
@@ -129,6 +132,9 @@
public void execute( ExecutionContext context,
Request request ) throws RepositorySourceException {
long size = largeValueMinimumSizeInBytes;
+ if (entityManager == null) {
+ throw new RepositorySourceException(JpaConnectorI18n.connectionIsNoLongerOpen.text(name));
+ }
RequestProcessor proc = model.createRequestProcessor(name,
context,
observer,
@@ -153,6 +159,14 @@
* @see org.jboss.dna.graph.connector.RepositoryConnection#close()
*/
public void close() {
+ if (entityManager != null) {
+ // Do this only once ...
+ try {
+ entityManagers.checkin(entityManager);
+ } finally {
+ entityManager = null;
+ }
+ }
}
}
Modified: trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaConnectorI18n.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaConnectorI18n.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaConnectorI18n.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -50,6 +50,7 @@
public static I18n workspaceAlreadyExists;
public static I18n workspaceDoesNotExist;
public static I18n unableToCreateWorkspaces;
+ public static I18n connectionIsNoLongerOpen;
public static I18n basicModelDescription;
Modified: trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/JpaSource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -210,7 +210,7 @@
private volatile String modelName;
private transient Model model;
private transient DataSource dataSource;
- private transient EntityManagerFactory entityManagerFactory;
+ private transient EntityManagers entityManagers;
private transient CachePolicy cachePolicy;
private transient RepositoryContext repositoryContext;
private transient UUID rootUuid = UUID.fromString(rootNodeUuid);
@@ -861,14 +861,12 @@
}
assert rootNodeUuid != null;
assert rootUuid != null;
- EntityManager entityManager = null;
- if (entityManagerFactory == null || !entityManagerFactory.isOpen()) {
+ if (entityManagers == null) {
// Create the JPA EntityManagerFactory by programmatically configuring Hibernate Entity Manager ...
Ejb3Configuration configurator = new Ejb3Configuration();
// Configure the entity classes ...
configurator.addAnnotatedClass(StoreOptionEntity.class);
- if (model != null) model.configure(configurator);
// Configure additional properties, which may be overridden by subclasses ...
configure(configurator);
@@ -913,56 +911,75 @@
setProperty(configurator, "hibernate.show_sql", String.valueOf(this.showSql));
}
- entityManagerFactory = configurator.buildEntityManagerFactory();
+ EntityManagerFactory entityManagerFactory = configurator.buildEntityManagerFactory();
+ try {
+ // Establish a connection and obtain the store options...
+ EntityManager entityManager = entityManagerFactory.createEntityManager();
+ try {
- // Establish a connection and obtain the store options...
- entityManager = entityManagerFactory.createEntityManager();
+ // Find and update/set the root node's UUID ...
+ StoreOptions options = new StoreOptions(entityManager);
+ UUID actualUuid = options.getRootNodeUuid();
+ if (actualUuid != null) {
+ this.setRootNodeUuid(actualUuid.toString());
+ } else {
+ options.setRootNodeUuid(this.rootUuid);
+ }
- // Find and update/set the root node's UUID ...
- StoreOptions options = new StoreOptions(entityManager);
- UUID actualUuid = options.getRootNodeUuid();
- if (actualUuid != null) {
- this.setRootNodeUuid(actualUuid.toString());
- } else {
- options.setRootNodeUuid(this.rootUuid);
- }
-
- // Find or set the type of model that will be used.
- String actualModelName = options.getModelName();
- if (actualModelName == null) {
- // This is a new store, so set to the specified model ...
- if (model == null) setModel(Models.DEFAULT.getName());
- assert model != null;
- options.setModelName(model);
- } else {
- try {
- setModel(actualModelName);
- } catch (Throwable e) {
- // The actual model name doesn't match what's available in the software ...
+ // Find or set the type of model that will be used.
+ String actualModelName = options.getModelName();
+ if (actualModelName == null) {
+ // This is a new store, so set to the specified model ...
+ if (model == null) setModel(Models.DEFAULT.getName());
+ assert model != null;
+ options.setModelName(model);
+ } else {
+ // Set the model to the what's listed in the database ...
+ try {
+ setModel(actualModelName);
+ } catch (Throwable e) {
+ // The actual model name doesn't match what's available in the software ...
+ String msg = JpaConnectorI18n.existingStoreSpecifiesUnknownModel.text(name, actualModelName);
+ throw new RepositorySourceException(msg);
+ }
+ }
+ } finally {
entityManager.close();
- entityManagerFactory.close();
- String msg = JpaConnectorI18n.existingStoreSpecifiesUnknownModel.text(name, actualModelName);
- throw new RepositorySourceException(msg);
}
+ } finally {
+ entityManagerFactory.close();
}
- entityManager.close();
- entityManagerFactory.close();
- // Now, create another entity manager with the classes from the correct model
+ // The model has not yet configured itself, so do that now ...
model.configure(configurator);
- entityManagerFactory = configurator.buildEntityManagerFactory();
- entityManager = entityManagerFactory.createEntityManager();
+
+ // Now, create another entity manager with the classes from the correct model and without changing the schema...
+ entityManagers = new EntityManagers(configurator);
}
- if (entityManager == null) {
- entityManager = entityManagerFactory.createEntityManager();
- }
Observer observer = repositoryContext != null ? repositoryContext.getObserver() : null;
- return new JpaConnection(getName(), observer, cachePolicy, entityManager, model, rootUuid, defaultWorkspace,
+ return new JpaConnection(getName(), observer, cachePolicy, entityManagers, model, rootUuid, defaultWorkspace,
getPredefinedWorkspaceNames(), largeValueSizeInBytes, isCreatingWorkspacesAllowed(),
compressData, referentialIntegrityEnforced);
}
/**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public synchronized void close() {
+ if (entityManagers != null) {
+ try {
+ // Close this object; existing connections will continue to work, and the last connection closed
+ // will actually shut the lights off...
+ entityManagers.close();
+ } finally {
+ entityManagers = null;
+ }
+ }
+ }
+
+ /**
* Set up the JPA configuration using Hibernate, except for the entity classes (which will already be configured when this
* method is called) and the data source or connection information (which will be set after this method returns). Subclasses
* may override this method to customize the configuration.
@@ -993,19 +1010,6 @@
setProperty(configuration, "hibernate.hbm2ddl.auto", "create");
}
- /**
- * Close any resources held by this source. This will ensure that all connections are closed.
- */
- public synchronized void close() {
- if (entityManagerFactory != null) {
- try {
- entityManagerFactory.close();
- } finally {
- entityManagerFactory = null;
- }
- }
- }
-
protected void setProperty( Ejb3Configuration configurator,
String propertyName,
String propertyValue ) {
Modified: trunk/extensions/dna-connector-store-jpa/src/main/resources/org/jboss/dna/connector/store/jpa/JpaConnectorI18n.properties
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/main/resources/org/jboss/dna/connector/store/jpa/JpaConnectorI18n.properties 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-store-jpa/src/main/resources/org/jboss/dna/connector/store/jpa/JpaConnectorI18n.properties 2009-09-03 16:11:39 UTC (rev 1190)
@@ -40,5 +40,6 @@
workspaceAlreadyExists = The source {0} already has a workspace named "{1}"
workspaceDoesNotExist = The source {0} has no workspace named "{1}"
unableToCreateWorkspaces = The source {0} does not allow creating workspaces
+connectionIsNoLongerOpen = This connection for source {0} has already been closed
basicModelDescription = Database model that stores node properties as opaque records and children as transparent records. Large property values are stored separately.
Modified: trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-store-jpa/src/test/java/org/jboss/dna/connector/store/jpa/JpaSourceTest.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -64,12 +64,8 @@
@After
public void afterEach() throws Exception {
- try {
- if (this.connection != null) {
- this.connection.close();
- }
- } finally {
- this.source.close();
+ if (this.connection != null) {
+ this.connection.close();
}
}
Modified: trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositorySource.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositorySource.java 2009-09-03 14:52:15 UTC (rev 1189)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositorySource.java 2009-09-03 16:11:39 UTC (rev 1190)
@@ -440,33 +440,32 @@
*
* @see org.jboss.dna.graph.connector.RepositorySource#getConnection()
*/
- public RepositoryConnection getConnection() throws RepositorySourceException {
-
+ public synchronized RepositoryConnection getConnection() throws RepositorySourceException {
+
String sourceName = getName();
if (sourceName == null || sourceName.trim().length() == 0) {
I18n msg = SVNRepositoryConnectorI18n.propertyIsRequired;
throw new RepositorySourceException(getName(), msg.text("name"));
}
-
+
String sourceUsername = getUsername();
if (sourceUsername == null || sourceUsername.trim().length() == 0) {
I18n msg = SVNRepositoryConnectorI18n.propertyIsRequired;
throw new RepositorySourceException(getUsername(), msg.text("username"));
}
-
+
String sourcePassword = getPassword();
if (sourcePassword == null) {
I18n msg = SVNRepositoryConnectorI18n.propertyIsRequired;
throw new RepositorySourceException(getPassword(), msg.text("password"));
}
-
+
String repositoryRootURL = getRepositoryRootURL();
if (repositoryRootURL == null || repositoryRootURL.trim().length() == 0) {
I18n msg = SVNRepositoryConnectorI18n.propertyIsRequired;
throw new RepositorySourceException(getRepositoryRootURL(), msg.text("repositoryRootURL"));
}
-
-
+
SVNRepository repos = null;
// Report the warnings for non-existant predefined workspaces
boolean reportWarnings = false;
@@ -494,7 +493,7 @@
url,
name);
}
- if (!SVNRepositoryUtil.isDirectory(repos,"")) {
+ if (!SVNRepositoryUtil.isDirectory(repos, "")) {
Logger.getLogger(getClass()).warn(SVNRepositoryConnectorI18n.pathForPredefinedWorkspaceIsNotDirectory,
url,
name);
@@ -515,13 +514,11 @@
String defaultURL = getDirectoryForDefaultWorkspace();
if (defaultURL != null) {
// Look for the entry at this path .....
- SVNRepository repository = SVNRepositoryUtil.createRepository(defaultURL,
- sourceUsername,
- sourcePassword);
+ SVNRepository repository = SVNRepositoryUtil.createRepository(defaultURL, sourceUsername, sourcePassword);
I18n warning = null;
if (!SVNRepositoryUtil.exist(repository)) {
warning = SVNRepositoryConnectorI18n.pathForPredefinedWorkspaceDoesNotExist;
- } else if (!SVNRepositoryUtil.isDirectory(repository,"")) {
+ } else if (!SVNRepositoryUtil.isDirectory(repository, "")) {
warning = SVNRepositoryConnectorI18n.pathForPredefinedWorkspaceIsNotDirectory;
} else {
// is a directory and is good to use!
@@ -537,6 +534,15 @@
sourceUsername, sourcePassword));
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositorySource#close()
+ */
+ public synchronized void close() {
+ this.availableWorspaceNames = null;
+ }
+
@Immutable
/* package */class SVNRepositoryCachePolicy implements CachePolicy {
private static final long serialVersionUID = 1L;
14 years, 8 months
DNA SVN: r1189 - trunk/dna-common/src/main/java/org/jboss/dna/common/text.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-09-03 10:52:15 -0400 (Thu, 03 Sep 2009)
New Revision: 1189
Modified:
trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java
Log:
Corrected the TokenStream.matches(String,String...) method to properly handle the ANY_VALUE on the first match.
Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java 2009-09-02 18:59:05 UTC (rev 1188)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java 2009-09-03 14:52:15 UTC (rev 1189)
@@ -684,7 +684,7 @@
ListIterator<Token> iter = tokens.listIterator(tokenIterator.previousIndex());
if (!iter.hasNext()) return false;
Token token = iter.next();
- if (currentExpected != ANY_VALUE || !token.matches(currentExpected)) return false;
+ if (currentExpected != ANY_VALUE && !token.matches(currentExpected)) return false;
for (String nextExpected : expectedForNextTokens) {
if (!iter.hasNext()) return false;
token = iter.next();
14 years, 8 months
DNA SVN: r1188 - in trunk/dna-common/src: test/java/org/jboss/dna/common/text and 1 other directory.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-09-02 14:59:05 -0400 (Wed, 02 Sep 2009)
New Revision: 1188
Modified:
trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java
trunk/dna-common/src/test/java/org/jboss/dna/common/text/TokenStreamBasicTokenizerTest.java
Log:
Minor fix to the new TokenStream class, plus multiple fixes for invalid use of @Override.
Modified: trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java
===================================================================
--- trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java 2009-09-02 18:58:39 UTC (rev 1187)
+++ trunk/dna-common/src/main/java/org/jboss/dna/common/text/TokenStream.java 2009-09-02 18:59:05 UTC (rev 1188)
@@ -1045,7 +1045,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.Token#type()
*/
- @Override
public final int type() {
return type;
}
@@ -1055,7 +1054,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.Token#startIndex()
*/
- @Override
public final int startIndex() {
return startIndex;
}
@@ -1065,7 +1063,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.Token#endIndex()
*/
- @Override
public final int endIndex() {
return endIndex;
}
@@ -1075,9 +1072,8 @@
*
* @see org.jboss.dna.common.text.TokenStream.Token#length()
*/
- @Override
public final int length() {
- return 0;
+ return endIndex - startIndex;
}
/**
@@ -1085,7 +1081,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.Token#matches(char)
*/
- @Override
public final boolean matches( char expected ) {
return length() == 1 && matchString().charAt(startIndex) == expected;
}
@@ -1095,7 +1090,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.Token#matches(java.lang.String)
*/
- @Override
public final boolean matches( String expected ) {
return matchString().substring(startIndex, endIndex).equals(expected);
}
@@ -1114,7 +1108,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.Token#position()
*/
- @Override
public Position position() {
return position;
}
@@ -1162,7 +1155,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.Tokens#addToken(org.jboss.dna.common.text.TokenStream.Position, int)
*/
- @Override
public void addToken( Position position,
int index ) {
addToken(position, index, index + 1, 0);
@@ -1173,7 +1165,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.Tokens#addToken(Position, int, int)
*/
- @Override
public final void addToken( Position position,
int startIndex,
int endIndex ) {
@@ -1192,9 +1183,8 @@
/**
* {@inheritDoc}
*
- * @see org.jboss.dna.common.text.TokenStream.Tokens#addToken(Position,int, int, int)
+ * @see org.jboss.dna.common.text.TokenStream.TokenFactory#addToken(Position,int, int, int)
*/
- @Override
public void addToken( Position position,
int startIndex,
int endIndex,
@@ -1207,9 +1197,8 @@
/**
* {@inheritDoc}
*
- * @see org.jboss.dna.common.text.TokenStream.Tokens#addToken(Position,int, int, int)
+ * @see org.jboss.dna.common.text.TokenStream.TokenFactory#addToken(Position,int, int, int)
*/
- @Override
public void addToken( Position position,
int startIndex,
int endIndex,
@@ -1236,7 +1225,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#hasNext()
*/
- @Override
public boolean hasNext() {
return lastIndex < maxIndex;
}
@@ -1246,7 +1234,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#index()
*/
- @Override
public int index() {
return lastIndex;
}
@@ -1256,7 +1243,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#position()
*/
- @Override
public Position position() {
return new Position(lineNumber, columnNumber);
}
@@ -1266,7 +1252,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#next()
*/
- @Override
public char next() {
if (lastIndex >= maxIndex) {
throw new NoSuchElementException();
@@ -1290,7 +1275,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#isNext(char)
*/
- @Override
public boolean isNext( char c ) {
int nextIndex = lastIndex + 1;
return nextIndex <= maxIndex && content[nextIndex] == c;
@@ -1301,7 +1285,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#isNext(char, char)
*/
- @Override
public boolean isNext( char nextChar1,
char nextChar2 ) {
int nextIndex1 = lastIndex + 1;
@@ -1314,7 +1297,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#isNext(char, char, char)
*/
- @Override
public boolean isNext( char nextChar1,
char nextChar2,
char nextChar3 ) {
@@ -1330,7 +1312,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#isNextAnyOf(char[])
*/
- @Override
public boolean isNextAnyOf( char[] characters ) {
int nextIndex = lastIndex + 1;
if (nextIndex <= maxIndex) {
@@ -1347,7 +1328,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#isNextAnyOf(java.lang.String)
*/
- @Override
public boolean isNextAnyOf( String characters ) {
int nextIndex = lastIndex + 1;
if (nextIndex <= maxIndex) {
@@ -1362,7 +1342,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.CharacterStream#isNextWhitespace()
*/
- @Override
public boolean isNextWhitespace() {
int nextIndex = lastIndex + 1;
return nextIndex <= maxIndex && Character.isWhitespace(content[nextIndex]);
@@ -1524,7 +1503,6 @@
*
* @see org.jboss.dna.common.text.TokenStream.Tokenizer#tokenize(CharacterStream, Tokens)
*/
- @Override
public void tokenize( CharacterStream input,
Tokens tokens ) throws ParsingException {
while (input.hasNext()) {
Modified: trunk/dna-common/src/test/java/org/jboss/dna/common/text/TokenStreamBasicTokenizerTest.java
===================================================================
--- trunk/dna-common/src/test/java/org/jboss/dna/common/text/TokenStreamBasicTokenizerTest.java 2009-09-02 18:58:39 UTC (rev 1187)
+++ trunk/dna-common/src/test/java/org/jboss/dna/common/text/TokenStreamBasicTokenizerTest.java 2009-09-02 18:59:05 UTC (rev 1188)
@@ -48,14 +48,12 @@
tokenizer = TokenStream.basicTokenizer(true);
final LinkedList<int[]> tokenValues = new LinkedList<int[]>();
tokenFactory = new Tokens() {
- @Override
public void addToken( Position position,
int index ) {
int[] token = new int[] {index, index + 1, 0};
tokenValues.add(token);
}
- @Override
public void addToken( Position position,
int startIndex,
int endIndex ) {
@@ -63,7 +61,6 @@
tokenValues.add(token);
}
- @Override
public void addToken( Position position,
int startIndex,
int endIndex,
14 years, 8 months