DNA SVN: r1182 - in branches/eclipse/org.jboss.dna.publish.ui.swt: icons/views and 5 other directories.
by dna-commits@lists.jboss.org
Author: elvisisking
Date: 2009-08-31 09:46:22 -0400 (Mon, 31 Aug 2009)
New Revision: 1182
Added:
branches/eclipse/org.jboss.dna.publish.ui.swt/icons/views/blank.gif
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/DnaResourceHelper.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/ReconnectToServerAction.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/ShowPublishedLocationsAction.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/PublishedLocationsDialog.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/views/DnaMessageConsole.java
Removed:
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/ServerContentProvider.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/plugin.properties
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/dialogs/DeleteServerDialog.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/ServerView.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishJob.java
branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishPage.java
Log:
Created a show published locations action and dialog that shows the workspaces the selected file has been published to. The dialog also allows the user to copy the workspace URL where the selected file is published at. The published locations are persisted across sessions. Refactored the content/label provider name from ServerContentProvider to DnaContentProvider. Refactored the DnaMessageConsole to be its own class. Added a job ID to all console messages. Added refresh (now called reconnect) to the context menu of the server view.
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/dna-web-jcr-rest-client-0.6-SNAPSHOT-jar-with-dependencies.jar
===================================================================
(Binary files differ)
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/views/blank.gif
===================================================================
(Binary files differ)
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/icons/views/blank.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.properties
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.properties 2009-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.properties 2009-08-31 13:46:22 UTC (rev 1182)
@@ -29,4 +29,5 @@
dnaCategory = DNA
publishAction.label = Publish
serverView = DNA Servers
+showPublishedLocationsAction.label = Show Published Locations
unpublishAction.label = Unpublish
\ No newline at end of file
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml 2009-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/plugin.xml 2009-08-31 13:46:22 UTC (rev 1182)
@@ -17,6 +17,22 @@
</separator>
</menu>
+ <!-- Show Published Locations action -->
+ <action
+ id="org.jboss.dna.web.jcr.rest.client.swt.showPublishedLocationsAction"
+ label="%showPublishedLocationsAction.label"
+ class="org.jboss.dna.web.jcr.rest.client.swt.actions.ShowPublishedLocationsAction"
+ icon="icons/views/blank.gif"
+ menubarPath="org.jboss.dna.web.jcr.rest.client.swt.contextMenu/group1"
+ enablesFor="1">
+ <enablement>
+ <and>
+ <objectClass name="org.eclipse.core.resources.IFile" />
+ <objectState name="persistentProperty" value="org.jboss.dna.web.jcr.rest.client.swt.publishedIn" />
+ </and>
+ </enablement>
+ </action>
+
<!-- Unpublish action -->
<action
id="org.jboss.dna.web.jcr.rest.client.swt.unpublishAction"
@@ -87,8 +103,8 @@
adaptable="true"
label="%decorator.label"
state="true"
- class="org.jboss.dna.web.jcr.rest.client.swt.views.ServerContentProvider"
- id="dnaDecorator">
+ class="org.jboss.dna.web.jcr.rest.client.swt.views.DnaContentProvider"
+ id="org.jboss.dna.web.jcr.rest.client.swt.dnaDecorator">
<description>
%decorator.description
</description>
@@ -97,7 +113,7 @@
<objectClass
name="org.jboss.dna.web.jcr.rest.client.domain.IDnaObject">
</objectClass>
- <objectClass
+ <objectClass
name="org.eclipse.core.resources.IFile">
</objectClass>
</or>
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/DnaResourceHelper.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/DnaResourceHelper.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/DnaResourceHelper.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -0,0 +1,258 @@
+/*
+ * 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;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.StringTokenizer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.QualifiedName;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.web.jcr.rest.client.ServerManager;
+import org.jboss.dna.web.jcr.rest.client.Status;
+import org.jboss.dna.web.jcr.rest.client.Status.Severity;
+import org.jboss.dna.web.jcr.rest.client.domain.Repository;
+import org.jboss.dna.web.jcr.rest.client.domain.Server;
+import org.jboss.dna.web.jcr.rest.client.domain.Workspace;
+
+/**
+ * The <code>DnaResourceHelper</code> knows how to get and set the property on a resource that indicates it has been published to
+ * one or more workspaces.
+ *
+ * @since 0.6
+ */
+public final class DnaResourceHelper {
+
+ // ===========================================================================================================================
+ // Constants
+ // ===========================================================================================================================
+
+ /**
+ * Delimiter between a workspace's properties.
+ *
+ * @since 0.6
+ */
+ private static final String ID_DELIM = "$"; //$NON-NLS-1$
+
+ /**
+ * Delimiter between workspaces.
+ *
+ * @since 0.6
+ */
+ private static final String DELIM = "|"; //$NON-NLS-1$
+
+ /**
+ * The name of the persisted file property indicating if the resource has been published. This property will only exist if the
+ * file has been published to at least one DNA repository. The value of the property is a list of DNA repository workspaces
+ * where this file has been published.
+ *
+ * @since 0.6
+ */
+ private static QualifiedName PUBLISHED_RESOURCE_PROPERTY = new QualifiedName(IUiConstants.PLUGIN_ID, "publishedIn"); //$NON-NLS-1$
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The server manager used by the helper to obtain workspaces.
+ *
+ * @since 0.6
+ */
+ private final ServerManager serverManager;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param serverManager the server manager used by this helper (never <code>null</code>)
+ * @since 0.6
+ */
+ public DnaResourceHelper( ServerManager serverManager ) {
+ CheckArg.isNotNull(serverManager, "serverManager"); //$NON-NLS-1$
+ this.serverManager = serverManager;
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * @param file the file that was just published
+ * @param workspace the workspace where the file was published
+ * @throws Exception if there is a problem setting the property
+ * @since 0.6
+ */
+ public void addPublishedProperty( IFile file,
+ Workspace workspace ) throws Exception {
+ CheckArg.isNotNull(file, "file"); //$NON-NLS-1$
+ CheckArg.isNotNull(workspace, "workspace"); //$NON-NLS-1$
+
+ Set<Workspace> workspaces = getPublishedOnWorkspaces(file);
+ workspaces.add(workspace);
+
+ // set new value
+ setPublishedOnPropertyValue(file, workspaces);
+ }
+
+ /**
+ * @param workspaces the workspaces used to create the property value
+ * @return the property value
+ * @since 0.6
+ */
+ private String createPublishedPropertyValue( Set<Workspace> workspaces ) {
+ StringBuilder value = new StringBuilder();
+
+ for (Workspace workspace : workspaces) {
+ value.append(createWorkspaceId(workspace)).append(DELIM);
+ }
+
+ return value.toString();
+ }
+
+ /**
+ * @param workspace the workspace whose identifier is being created
+ * @return the ID
+ * @since 0.6
+ */
+ private String createWorkspaceId( Workspace workspace ) {
+ StringBuilder result = new StringBuilder();
+ result.append(workspace.getServer().getUrl()).append(ID_DELIM).append(workspace.getServer().getUser()).append(ID_DELIM);
+ result.append(workspace.getRepository().getName()).append(ID_DELIM);
+ result.append(workspace.getName());
+
+ return result.toString();
+ }
+
+ /**
+ * @param file the file whose <code>Workspace</code>s it has been published on is being requested (never <code>null</code>)
+ * @return the workspaces (never <code>null</code>)
+ * @throws Exception if there is a problem reading one of the file's persistent properties or a problem with the server
+ * manager
+ * @since 0.6
+ */
+ public Set<Workspace> getPublishedOnWorkspaces( IFile file ) throws Exception {
+ CheckArg.isNotNull(file, "file"); //$NON-NLS-1$
+
+ Set<Workspace> publishedOnWorkspaces = null;
+ String value = file.getPersistentProperty(PUBLISHED_RESOURCE_PROPERTY);
+
+ if (value == null) {
+ publishedOnWorkspaces = new HashSet<Workspace>(1);
+ } else {
+ StringTokenizer wsTokenizer = new StringTokenizer(value, DELIM);
+ publishedOnWorkspaces = new HashSet<Workspace>(wsTokenizer.countTokens());
+
+ while (wsTokenizer.hasMoreTokens()) {
+ StringTokenizer propsTokenizer = new StringTokenizer(wsTokenizer.nextToken(), ID_DELIM);
+
+ PARSE_WORKSPACE: while (propsTokenizer.hasMoreTokens()) {
+ String url = propsTokenizer.nextToken();
+ String user = propsTokenizer.nextToken();
+ Server server = this.serverManager.findServer(url, user);
+
+ if ((server != null) && this.serverManager.ping(server).isOk()) {
+ Collection<Repository> repositories = this.serverManager.getRepositories(server);
+
+ if (!repositories.isEmpty()) {
+ String repositoryName = propsTokenizer.nextToken();
+
+ for (Repository repository : repositories) {
+ if (repository.getName().equals(repositoryName)) {
+ Collection<Workspace> workspaces = this.serverManager.getWorkspaces(repository);
+
+ if (!workspaces.isEmpty()) {
+ String workspaceName = propsTokenizer.nextToken();
+
+ for (Workspace workspace : workspaces) {
+ if (workspace.getName().equals(workspaceName)) {
+ publishedOnWorkspaces.add(workspace);
+ break PARSE_WORKSPACE;
+ }
+ }
+ }
+
+ }
+ }
+ }
+ } else {
+ // this will remove workspace as being one that the file has been published on
+ break PARSE_WORKSPACE;
+ }
+ }
+ }
+ }
+
+ return publishedOnWorkspaces;
+ }
+
+ /**
+ * @param file the file whose published status is being requested (never <code>null</code>)
+ * @return <code>true</code> if the file has been published to any DNA repository
+ * @since 0.6
+ */
+ public boolean isPublished( IFile file ) {
+ CheckArg.isNotNull(file, "file"); //$NON-NLS-1$
+
+ try {
+ return !getPublishedOnWorkspaces(file).isEmpty();
+ } catch (Exception e) {
+ Activator.getDefault().log(new Status(Severity.ERROR, RestClientI18n.publishedResourcePropertyErrorMsg.text(file), e));
+ }
+
+ return false;
+ }
+
+ /**
+ * @param file the file that was just unpublished
+ * @param workspace the workspace where the file was unpublished
+ * @throws Exception if there is a problem setting the property
+ * @since 0.6
+ */
+ public void removePublishedProperty( IFile file,
+ Workspace workspace ) throws Exception {
+ CheckArg.isNotNull(file, "file"); //$NON-NLS-1$
+ CheckArg.isNotNull(workspace, "workspace"); //$NON-NLS-1$
+
+ Set<Workspace> workspaces = getPublishedOnWorkspaces(file);
+ workspaces.remove(workspace);
+
+ // set new value
+ setPublishedOnPropertyValue(file, workspaces);
+ }
+
+ private void setPublishedOnPropertyValue( IFile file,
+ Set<Workspace> workspaces ) throws CoreException {
+ if ((workspaces == null) || workspaces.isEmpty()) {
+ file.setPersistentProperty(PUBLISHED_RESOURCE_PROPERTY, null);
+ } else {
+ String value = createPublishedPropertyValue(workspaces);
+ file.setPersistentProperty(PUBLISHED_RESOURCE_PROPERTY, value);
+ }
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/DnaResourceHelper.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/IUiConstants.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/IUiConstants.java 2009-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/IUiConstants.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -35,13 +35,6 @@
*/
String PLUGIN_ID = "org.jboss.dna.web.jcr.rest.client.swt"; //$NON-NLS-1$
- /**
- * The identifier and type of the DNA Message Console. This is where publishing and unpublishing operations are logged.
- *
- * @since 0.6
- */
- String DNA_CONSOLE_ID = "org.jboss.dna.web.jcr.rest.client.swt.views.DnaConsole"; //$NON-NLS-1$
-
String ICON_FOLDER = "icons/"; //$NON-NLS-1$
//
@@ -64,6 +57,8 @@
String VIEWS_ICON_FOLDER = ICON_FOLDER + "views/"; //$NON-NLS-1$
+ String BLANK_IMAGE = VIEWS_ICON_FOLDER + "blank.gif"; //$NON-NLS-1$
+
String COLLAPSE_ALL_IMAGE = VIEWS_ICON_FOLDER + "collapse_all.gif"; //$NON-NLS-1$
String DELETE_SERVER_IMAGE = VIEWS_ICON_FOLDER + "delete_server.gif"; //$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-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -45,6 +45,10 @@
public static I18n deleteServerDialogOneServerMsg;
public static I18n deleteServerDialogTitle;
+ public static I18n dnaConsoleName;
+ public static I18n dnaConsoleProblemCreatingHyperlinkMsg;
+ public static I18n dnaConsoleFilePathNotFoundMsg;
+
public static I18n editServerActionText;
public static I18n editServerActionToolTip;
@@ -54,14 +58,27 @@
public static I18n newServerActionText;
public static I18n newServerActionToolTip;
+
+ public static I18n publishedLocationsDialogCopyUrlButton;
+ public static I18n publishedLocationsDialogCopyUrlButtonToolTip;
+ public static I18n publishedLocationsDialogErrorObtainingUrlMsg;
+ public static I18n publishedLocationsDialogFileUrlColumnHeader;
+ public static I18n publishedLocationsDialogMsg;
+ public static I18n publishedLocationsDialogRepositoryColumnHeader;
+ public static I18n publishedLocationsDialogServerUrlColumnHeader;
+ public static I18n publishedLocationsDialogTitle;
+ public static I18n publishedLocationsDialogUserColumnHeader;
+ public static I18n publishedLocationsDialogWorkspaceColumnHeader;
public static I18n publishedResourcePropertyErrorMsg;
- public static I18n publishJobConsoleName;
+ public static I18n publishJobCanceled;
+ public static I18n publishJobLongDurationMsg;
+ public static I18n publishJobShortDurationMsg;
public static I18n publishJobPublish;
public static I18n publishJobPublishCanceledMsg;
- public static I18n publishJobProblemCreatingHyperlinkMsg;
public static I18n publishJobPublishFile;
+ public static I18n publishJobPublishFile2;
public static I18n publishJobPublishFileFailed;
public static I18n publishJobPublishFileInfo;
public static I18n publishJobPublishFileWarning;
@@ -111,8 +128,6 @@
public static I18n publishWizardUnpublishTitle;
public static I18n publishWizardUnpublishErrorMsg;
- public static I18n refreshActionToolTip;
-
public static I18n serverManagerGetRepositoriesExceptionMsg;
public static I18n serverManagerGetWorkspacesExceptionMsg;
@@ -136,12 +151,17 @@
public static I18n serverPageUserLabel;
public static I18n serverPageUserToolTip;
+ public static I18n serverReconnectActionText;
+ public static I18n serverReconnectActionToolTip;
+
public static I18n serverViewToolTip;
public static I18n serverWizardEditServerErrorMsg;
public static I18n serverWizardEditServerTitle;
public static I18n serverWizardNewServerErrorMsg;
public static I18n serverWizardNewServerTitle;
+
+ public static I18n showPublishedLocationsErrorMsg;
public static I18n testServerActionText;
public static I18n testServerActionToolTip;
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-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/RestClientI18n.properties 2009-08-31 13:46:22 UTC (rev 1182)
@@ -26,7 +26,7 @@
collapseActionToolTip = Collapse All
-deleteServerActionText = Delete Server
+deleteServerActionText = Discard
deleteServerActionToolTip = Delete server from the server registry
deleteServerDialogErrorsOccurredMsg = There were errors deleting servers from the server registry. See log for more details.
@@ -37,6 +37,10 @@
editServerActionText = Server Properties
editServerActionToolTip = Edit server properties
+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.
+
errorDialogTitle = Error
missingImage = The following image cannot be found "{0}"
@@ -44,29 +48,42 @@
newServerActionText = New Server
newServerActionToolTip = Create a new server
+publishedLocationsDialogCopyUrlButton = Copy URL
+publishedLocationsDialogCopyUrlButtonToolTip = Copy to the clipboard the selected workspace URL where the file is published
+publishedLocationsDialogErrorObtainingUrlMsg = Error obtaining URL
+publishedLocationsDialogFileUrlColumnHeader = Published URL
+publishedLocationsDialogMsg = The file "{0}" has been published to the following DNA workspaces:
+publishedLocationsDialogRepositoryColumnHeader = Repository
+publishedLocationsDialogServerUrlColumnHeader = Server URL
+publishedLocationsDialogTitle = Published Locations
+publishedLocationsDialogUserColumnHeader = User
+publishedLocationsDialogWorkspaceColumnHeader = Workspace
+
publishedResourcePropertyErrorMsg = Error obtaining the "published" property from the resource "{0}"
-publishJobConsoleName = DNA
-publishJobProblemCreatingHyperlinkMsg = Unexpected problem creating hyperlink in DNA Console view
+publishJobCanceled = Job {0} was canceled. See log for details.
+publishJobLongDurationMsg = {0} hour(s), {1} minute(s), {2} second(s)
+publishJobShortDurationMsg = less than 1 second
publishJobPublish = [{0}] Publishing {4} file(s) to server "{1}" (repository "{2}", workspace "{3}") ...
-publishJobPublishCanceledMsg = [{0}] ! Publishing to server "{1}" (repository "{2}", workspace "{3}") was canceled after {4} file(s) out of {5} were processed.\n
-publishJobPublishFile = \t[{0}] + Published file "{1}"
-publishJobPublishFileFailed = \t[{0}] * Publishing file "{1}" generated an ERROR message. See log.
-publishJobPublishFileInfo = \t[{0}] i Publishing file "{1}" generated an INFO message. See log.
-publishJobPublishFileWarning = \t[{0}] w Publishing file "{1}" generated a WARNING message. See log.
-publishJobPublishFinishedMsg = [{0}] Done publishing ({4} milliseconds) to server "{1}" (repository "{2}", workspace "{3}").\n
-publishJobPublishName = DNA Publish
-publishJobPublishTaskName = Publishing resources
+publishJobPublishCanceledMsg = [{0}] !! Publishing to server "{1}" (repository "{2}", workspace "{3}") was canceled after {4} file(s) out of {5} were processed.\n
+publishJobPublishFile = \t[{0}] ++ Published file "{1}" to URL\
+publishJobPublishFile2 = "{0}"
+publishJobPublishFileFailed = \t[{0}] ERROR Publishing file "{1}" generated an ERROR message. See log.
+publishJobPublishFileInfo = \t[{0}] INFO Publishing file "{1}" generated an INFO message. See log.
+publishJobPublishFileWarning = \t[{0}] WARN Publishing file "{1}" generated a WARNING message. See log.
+publishJobPublishFinishedMsg = [{0}] Done publishing. Elapsed time: {1}. \n
+publishJobPublishName = DNA Publish [{0}]
+publishJobPublishTaskName = Publishing resources [{0}]
publishJobUnexpectedErrorMsg = Unexpected error occurred. See log for more details.
publishJobUnpublish = [{0}] Unpublishing {4} file(s) from server "{1}" (repository "{2}", workspace "{3}") ...
-publishJobUnpublishCanceledMsg = [{0}] ! Unpublishing from server "{1}" (repository "{2}", workspace "{3}") was canceled after {4} file(s) out of {5} were processed.\n
-publishJobUnpublishFile = \t[{0}] - Unpublished file "{1}"
-publishJobUnpublishFileFailed = \t[{0}] * Unpublishing file "{0}" generated an ERROR message. See log.
-publishJobUnpublishFileInfo = \t[{0}] i Unpublishing file "{1}" generated an INFO message. See log.
-publishJobUnpublishFileWarning = \t[{0}] w Unpublishing file "{1}" generated a WARNING message. See log.
-publishJobUnpublishFinishedMsg = [{0}] Done unpublishing ({4} milliseconds) from server "{1}" (repository "{2}", workspace "{3}").\n
-publishJobUnpublishName = DNA Unpublish
-publishJobUnpublishTaskName = Unpublishing resources
+publishJobUnpublishCanceledMsg = [{0}] !! Unpublishing from server "{1}" (repository "{2}", workspace "{3}") was canceled after {4} file(s) out of {5} were processed.\n
+publishJobUnpublishFile = \t[{0}] -- Unpublished file "{1}"
+publishJobUnpublishFileFailed = \t[{0}] ERROR Unpublishing file "{0}" generated an ERROR message. See log.
+publishJobUnpublishFileInfo = \t[{0}] INFO Unpublishing file "{1}" generated an INFO message. See log.
+publishJobUnpublishFileWarning = \t[{0}] WARN Unpublishing file "{1}" generated a WARNING message. See log.
+publishJobUnpublishFinishedMsg = [{0}] Done unpublishing. Elapsed time: {1}. \n
+publishJobUnpublishName = DNA Unpublish [{0}]
+publishJobUnpublishTaskName = Unpublishing resources [{0}]
publishPagePublishTitle = Publish the selected resources
publishPageLocationGroupTitle = Location
@@ -100,7 +117,8 @@
publishWizardUnpublishErrorMsg = Error Unpublishing
publishWizardUnpublishTitle = Unpublish
-refreshActionToolTip = Refresh
+serverReconnectActionText = Reconnect
+serverReconnectActionToolTip = Reconnect to selected servers or all servers if no servers selected
serverManagerGetRepositoriesExceptionMsg = There was a problem obtaining repositories for the server "{0}."
serverManagerGetWorkspacesExceptionMsg = There was a problem obtaining workspaces for repository "{0}."
@@ -132,5 +150,7 @@
serverWizardNewServerErrorMsg = There were errors creating a new server. See log for more details.
serverWizardNewServerTitle = New Server
+showPublishedLocationsErrorMsg = Unexpected problem showing published on locations. See log for more details.
+
testServerActionText = Connect
testServerActionToolTip = Connect to the server identified by the abover URL, user, and password
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-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/Utils.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -23,13 +23,7 @@
*/
package org.jboss.dna.web.jcr.rest.client.swt;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.StringTokenizer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
@@ -39,7 +33,6 @@
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.web.jcr.rest.client.Status;
import org.jboss.dna.web.jcr.rest.client.Status.Severity;
-import org.jboss.dna.web.jcr.rest.client.domain.Workspace;
/**
* @since 0.6
@@ -47,71 +40,10 @@
public final class Utils {
// ===========================================================================================================================
- // Constants
- // ===========================================================================================================================
-
- /**
- * Delimiter between a workspace's properties.
- *
- * @since 0.6
- */
- private static final String ID_DELIM = "$"; //$NON-NLS-1$
-
- /**
- * Delimiter between workspaces.
- *
- * @since 0.6
- */
- private static final String DELIM = "|"; //$NON-NLS-1$
-
- /**
- * The name of the persisted file property indicating if the resource has been published. This property will only exist if the
- * file has been published to at least one DNA repository. The value of the property is a list of DNA repository workspaces
- * where this file has been published.
- *
- * @since 0.6
- */
- private static QualifiedName PUBLISHED_RESOURCE_PROPERTY = new QualifiedName(IUiConstants.PLUGIN_ID, "publishedIn"); //$NON-NLS-1$
-
- // ===========================================================================================================================
// Class Methods
// ===========================================================================================================================
/**
- * @param file the file that was just published
- * @param workspace the workspace where the file was published
- * @since 0.6
- */
- public static void addPublishedProperty( IFile file,
- Workspace workspace ) {
- CheckArg.isNotNull(file, "file"); //$NON-NLS-1$
- CheckArg.isNotNull(workspace, "workspace"); //$NON-NLS-1$
-
- String wsValue = createWorkspaceId(workspace);
-
- try {
- Set<String> workspaces = null;
-
- // get current value
- String value = file.getPersistentProperty(PUBLISHED_RESOURCE_PROPERTY);
-
- if (value == null) {
- workspaces = new HashSet<String>(1);
- } else {
- workspaces = parsePublishedPropertyValue(value);
- }
-
- workspaces.add(wsValue);
-
- // set new value
- value = createPublishedPropertyValue(workspaces);
- file.setPersistentProperty(PUBLISHED_RESOURCE_PROPERTY, value);
- } catch (CoreException e) {
- Activator.getDefault().log(new Status(Severity.ERROR, RestClientI18n.publishedResourcePropertyErrorMsg.text(file), e));
- }
- }
-
- /**
* 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
@@ -181,35 +113,6 @@
}
/**
- * @param workspaces the workspaces used to create the property value
- * @return the property value
- * @since 0.6
- */
- private static String createPublishedPropertyValue( Set<String> workspaces ) {
- StringBuilder value = new StringBuilder();
-
- for (String workspace : workspaces) {
- value.append(workspace).append(DELIM);
- }
-
- return value.toString();
- }
-
- /**
- * @param workspace the workspace whose identifier is being created
- * @return the ID
- * @since 0.6
- */
- private static String createWorkspaceId( Workspace workspace ) {
- StringBuilder result = new StringBuilder();
- result.append(workspace.getServer().getUrl()).append(ID_DELIM).append(workspace.getServer().getUser()).append(ID_DELIM);
- result.append(workspace.getRepository().getName()).append(ID_DELIM);
- result.append(workspace.getName());
-
- return result.toString();
- }
-
- /**
* The OK status does not have an image.
*
* @param status the status whose image is being requested (never <code>null</code>)
@@ -257,72 +160,6 @@
return null;
}
- /**
- * @param file the file whose published status is being requested
- * @return <code>true</code> if the file has been published to any DNA repository
- * @since 0.6
- */
- public static boolean isPublished( IFile file ) {
- CheckArg.isNotNull(file, "file"); //$NON-NLS-1$
-
- try {
- return (file.getPersistentProperty(PUBLISHED_RESOURCE_PROPERTY) != null);
- } catch (CoreException e) {
- Activator.getDefault().log(new Status(Severity.ERROR, RestClientI18n.publishedResourcePropertyErrorMsg.text(file), e));
- }
-
- return false;
- }
-
- /**
- * @param value the property value being parsed
- * @return a collection of workspace identifiers
- * @since 0.6
- */
- private static Set<String> parsePublishedPropertyValue( String value ) {
- StringTokenizer st = new StringTokenizer(value, DELIM);
- Set<String> workspaces = new HashSet<String>(st.countTokens());
-
- while (st.hasMoreTokens()) {
- workspaces.add(st.nextToken());
- }
-
- return workspaces;
- }
-
- /**
- * @param file the file that was just unpublished
- * @param workspace the workspace where the file was unpublished
- * @since 0.6
- */
- public static void removePublishedProperty( IFile file,
- Workspace workspace ) {
- CheckArg.isNotNull(file, "file"); //$NON-NLS-1$
- CheckArg.isNotNull(workspace, "workspace"); //$NON-NLS-1$
-
- String wsValue = createWorkspaceId(workspace);
-
- try {
- String value = file.getPersistentProperty(PUBLISHED_RESOURCE_PROPERTY);
-
- if (value != null) {
- Set<String> workspaces = parsePublishedPropertyValue(value);
- workspaces.remove(wsValue);
-
- if (workspaces.isEmpty()) {
- // no other workspaces so remove property
- file.setPersistentProperty(PUBLISHED_RESOURCE_PROPERTY, null);
- } else {
- // set new value
- value = createPublishedPropertyValue(workspaces);
- file.setPersistentProperty(PUBLISHED_RESOURCE_PROPERTY, value);
- }
- }
- } catch (CoreException e) {
- Activator.getDefault().log(new Status(Severity.ERROR, RestClientI18n.publishedResourcePropertyErrorMsg.text(file), e));
- }
- }
-
// ===========================================================================================================================
// Constructors
// ===========================================================================================================================
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/ReconnectToServerAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/ReconnectToServerAction.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/ReconnectToServerAction.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -0,0 +1,106 @@
+/*
+ * 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.actions;
+
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.REFRESH_IMAGE;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.jboss.dna.web.jcr.rest.client.IServerRegistryListener;
+import org.jboss.dna.web.jcr.rest.client.ServerRegistryEvent;
+import org.jboss.dna.web.jcr.rest.client.swt.Activator;
+import org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n;
+
+/**
+ * The <code>ReconnectToServerAction</code> tries to reconnect to one or more selected servers or to all servers if none are
+ * selected. This action must be registered to received server registry events.
+ *
+ * @since 0.6
+ */
+public final class ReconnectToServerAction extends Action implements IServerRegistryListener {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The server view tree viewer.
+ *
+ * @since 0.6
+ */
+ private final TreeViewer viewer;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param viewer the server view tree viewer
+ * @since 0.6
+ */
+ public ReconnectToServerAction( TreeViewer viewer ) {
+ super(RestClientI18n.serverReconnectActionText.text());
+ setToolTipText(RestClientI18n.serverReconnectActionToolTip.text());
+ setImageDescriptor(Activator.getDefault().getImageDescriptor(REFRESH_IMAGE));
+ setEnabled(false);
+
+ this.viewer = viewer;
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.action.Action#run()
+ * @since 0.6
+ */
+ @Override
+ public void run() {
+ IStructuredSelection selection = (IStructuredSelection)this.viewer.getSelection();
+
+ if (selection.size() == 0) {
+ this.viewer.refresh();
+ } else {
+ for (Object server : selection.toArray()) {
+ this.viewer.refresh(server);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.web.jcr.rest.client.IServerRegistryListener#serverRegistryChanged(org.jboss.dna.web.jcr.rest.client.ServerRegistryEvent)
+ * @since 0.6
+ */
+ @Override
+ public Exception[] serverRegistryChanged( ServerRegistryEvent event ) {
+ setEnabled(!event.getServerManager().getServers().isEmpty());
+ return null;
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/ReconnectToServerAction.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/actions/ShowPublishedLocationsAction.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/ShowPublishedLocationsAction.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/ShowPublishedLocationsAction.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -0,0 +1,141 @@
+/*
+ * 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.actions;
+
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.DELETE_SERVER_IMAGE;
+import java.util.Set;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IObjectActionDelegate;
+import org.eclipse.ui.IWorkbenchPart;
+import org.jboss.dna.web.jcr.rest.client.ServerManager;
+import org.jboss.dna.web.jcr.rest.client.Status;
+import org.jboss.dna.web.jcr.rest.client.Status.Severity;
+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.DnaResourceHelper;
+import org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n;
+import org.jboss.dna.web.jcr.rest.client.swt.dialogs.PublishedLocationsDialog;
+
+/**
+ * The <code>PublishAction</code> controls the publishing of one or more {@link org.eclipse.core.resources.IResource}s to a DNA
+ * repository.
+ *
+ * @since 0.6
+ */
+public final class ShowPublishedLocationsAction extends Action implements IObjectActionDelegate {
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The current workspace selection.
+ *
+ * @since 0.6
+ */
+ private IStructuredSelection selection;
+
+ /**
+ * The active part's Shell.
+ *
+ * @since 0.6
+ */
+ private Shell shell;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ public ShowPublishedLocationsAction() {
+ super(RestClientI18n.deleteServerActionText.text(), Activator.getDefault().getImageDescriptor(DELETE_SERVER_IMAGE));
+ setToolTipText(RestClientI18n.deleteServerActionToolTip.text());
+ setEnabled(false);
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
+ * @since 0.6
+ */
+ @Override
+ public void run( IAction action ) {
+ assert ((this.selection != null) && (this.selection.size() == 1));
+ assert (this.selection.getFirstElement() instanceof IFile);
+
+ // open dialog
+ ServerManager serverManager = Activator.getDefault().getServerManager();
+ DnaResourceHelper resourceHelper = new DnaResourceHelper(serverManager);
+
+ try {
+ Set<Workspace> workspaces = resourceHelper.getPublishedOnWorkspaces((IFile)this.selection.getFirstElement());
+ new PublishedLocationsDialog(this.shell, serverManager, (IFile)this.selection.getFirstElement(), workspaces).open();
+ } catch (Exception e) {
+ Activator.getDefault().log(new Status(Severity.ERROR, RestClientI18n.showPublishedLocationsErrorMsg.text(), e));
+ MessageDialog.openError(this.shell,
+ RestClientI18n.errorDialogTitle.text(),
+ RestClientI18n.showPublishedLocationsErrorMsg.text());
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction,
+ * org.eclipse.jface.viewers.ISelection)
+ * @since 0.6
+ */
+ @Override
+ public void selectionChanged( IAction action,
+ ISelection selection ) {
+ if (selection instanceof IStructuredSelection) {
+ this.selection = (IStructuredSelection)selection;
+ } else {
+ this.selection = null;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.IObjectActionDelegate#setActivePart(org.eclipse.jface.action.IAction, org.eclipse.ui.IWorkbenchPart)
+ * @since 0.6
+ */
+ @Override
+ public void setActivePart( IAction action,
+ IWorkbenchPart targetPart ) {
+ this.shell = targetPart.getSite().getShell();
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/actions/ShowPublishedLocationsAction.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/dialogs/DeleteServerDialog.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/DeleteServerDialog.java 2009-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/DeleteServerDialog.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -38,6 +38,7 @@
import org.jboss.dna.web.jcr.rest.client.domain.Server;
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;
/**
* The <code>DeleteServerDialog</code> class provides a UI for deleting a {@link Server server}.
@@ -126,4 +127,16 @@
return null;
}
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#initializeBounds()
+ * @since 0.6
+ */
+ @Override
+ protected void initializeBounds() {
+ super.initializeBounds();
+ Utils.centerAndSizeShellRelativeToDisplay(getShell(), 75, 75);
+ }
+
}
Added: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/PublishedLocationsDialog.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/PublishedLocationsDialog.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/PublishedLocationsDialog.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -0,0 +1,513 @@
+/*
+ * 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.dialogs;
+
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.BLANK_IMAGE;
+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.REPOSITORY_IMAGE;
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.SERVER_IMAGE;
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.WORKSPACE_IMAGE;
+import java.io.File;
+import java.util.Collection;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITableLabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TableLayout;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.Clipboard;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+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.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.web.jcr.rest.client.ServerManager;
+import org.jboss.dna.web.jcr.rest.client.Status;
+import org.jboss.dna.web.jcr.rest.client.Status.Severity;
+import org.jboss.dna.web.jcr.rest.client.domain.Server;
+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;
+
+/**
+ * The <code>PublishedLocationsDialog</code> class provides a UI for viewing a list of {@link Server servers} a selected file has
+ * been published to.
+ *
+ * @since 0.6
+ */
+public final class PublishedLocationsDialog extends MessageDialog {
+
+ // ===========================================================================================================================
+ // Constants
+ // ===========================================================================================================================
+
+ /**
+ * The column index of the server URL.
+ *
+ * @since 0.6
+ */
+ private static final int SERVER_URL_COL = 0;
+
+ /**
+ * The column index of the server user.
+ *
+ * @since 0.6
+ */
+ private static final int USER_COL = 1;
+
+ /**
+ * The column index of the repository name.
+ *
+ * @since 0.6
+ */
+ private static final int REPOSITORY_COL = 2;
+
+ /**
+ * The column index of the workspace name.
+ *
+ * @since 0.6
+ */
+ private static final int WORKSPACE_COL = 3;
+
+ /**
+ * The column index of the URL where the file was published.
+ *
+ * @since 0.6
+ */
+ private static final int FILE_URL_COL = 4;
+
+ /**
+ * The column indexes of all columns.
+ *
+ * @since 0.6
+ */
+ private static final int[] COLUMNS = {SERVER_URL_COL, USER_COL, REPOSITORY_COL, WORKSPACE_COL, FILE_URL_COL};
+
+ /**
+ * The column headers.
+ *
+ * @since 0.6
+ */
+ private static final String[] HEADERS = {RestClientI18n.publishedLocationsDialogServerUrlColumnHeader.text(),
+ RestClientI18n.publishedLocationsDialogUserColumnHeader.text(),
+ RestClientI18n.publishedLocationsDialogRepositoryColumnHeader.text(),
+ RestClientI18n.publishedLocationsDialogWorkspaceColumnHeader.text(),
+ RestClientI18n.publishedLocationsDialogFileUrlColumnHeader.text(),};
+
+ // ===========================================================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The button that copies the file URL to the clipboard.
+ *
+ * @since 0.6
+ */
+ private Button btnCopy;
+
+ /**
+ * The file whose workspaces it was published to is being displayed by this dialog.
+ *
+ * @since 0.6
+ */
+ private final IFile file;
+
+ /**
+ * The server manager who can obtain the URL for the file at each of the workspaces.
+ *
+ * @since 0.6
+ */
+ private final ServerManager serverManager;
+
+ /**
+ * The viewer of the table holding the published locations.
+ *
+ * @since 0.6
+ */
+ private TableViewer viewer;
+
+ /**
+ * Collection of workspaces the selected file has been published to.
+ *
+ * @since 0.6
+ */
+ private final Collection<Workspace> workspaces;
+
+ // ===========================================================================================================================
+ // Constructors
+ // ===========================================================================================================================
+
+ /**
+ * @param parentShell the dialog parent
+ * @param serverManager the server manager that this dialog will get URLs from (never <code>null</code>)
+ * @param file the file whose workspaces it has been published on is being requested (never <code>null</code>)
+ * @param workspaces the workspaces (never <code>null</code>)
+ * @since 0.6
+ */
+ public PublishedLocationsDialog( Shell parentShell,
+ ServerManager serverManager,
+ IFile file,
+ Collection<Workspace> workspaces ) {
+ super(parentShell, RestClientI18n.publishedLocationsDialogTitle.text(), Activator.getDefault().getImage(DNA_IMAGE_16x),
+ RestClientI18n.publishedLocationsDialogMsg.text(file.getFullPath()), MessageDialog.INFORMATION,
+ new String[] {IDialogConstants.OK_LABEL}, 0);
+
+ CheckArg.isNotNull(serverManager, "serverManager"); //$NON-NLS-1$
+ CheckArg.isNotNull(file, "file"); //$NON-NLS-1$
+ CheckArg.isNotNull(workspaces, "workspaces"); //$NON-NLS-1$
+
+ this.file = file;
+ this.serverManager = serverManager;
+ this.workspaces = workspaces;
+
+ // make sure dialog is resizable
+ setShellStyle(getShellStyle() | SWT.RESIZE);
+ }
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.MessageDialog#createCustomArea(org.eclipse.swt.widgets.Composite)
+ * @since 0.6
+ */
+ @Override
+ protected Control createCustomArea( Composite parent ) {
+ // layout consists of a panel that contains a table and a button
+ Composite panel = new Composite(parent, SWT.NONE);
+ panel.setLayout(new GridLayout(2, false));
+ panel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+ //
+ // construct table
+ //
+
+ this.viewer = new TableViewer(panel, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+ LocationsTableProvider provider = new LocationsTableProvider();
+ this.viewer.setLabelProvider(provider);
+ this.viewer.setContentProvider(provider);
+ this.viewer.addSelectionChangedListener(new ISelectionChangedListener() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
+ * @since 0.6
+ */
+ @Override
+ public void selectionChanged( SelectionChangedEvent e ) {
+ handleTableSelection();
+ }
+ });
+
+ // configure table
+ Table table = this.viewer.getTable();
+ table.setLayout(new TableLayout());
+ table.setLayoutData(new GridData(GridData.FILL_BOTH));
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+
+ // create columns
+ for (int numCols = COLUMNS.length, i = 0; i < numCols; ++i) {
+ TableColumn column = new TableColumn(table, SWT.LEFT);
+ column.setText(HEADERS[i]);
+
+ // set image
+ Image image = null;
+
+ if ((i == SERVER_URL_COL) || (i == USER_COL)) {
+ image = Activator.getDefault().getImage(SERVER_IMAGE);
+ } else if (i == REPOSITORY_COL) {
+ image = Activator.getDefault().getImage(REPOSITORY_IMAGE);
+ } else if (i == WORKSPACE_COL) {
+ image = Activator.getDefault().getImage(WORKSPACE_IMAGE);
+ } else {
+ image = Activator.getDefault().getImage(BLANK_IMAGE);
+ }
+
+ column.setImage(image);
+ }
+
+ // populate the table
+ this.viewer.setInput(this);
+
+ // size columns
+ for (TableColumn column : table.getColumns()) {
+ column.pack();
+ column.setWidth(column.getWidth() + 10);
+ }
+
+ //
+ // construct button
+ //
+
+ this.btnCopy = new Button(panel, SWT.PUSH);
+ this.btnCopy.setText(RestClientI18n.publishedLocationsDialogCopyUrlButton.text());
+ this.btnCopy.setToolTipText(RestClientI18n.publishedLocationsDialogCopyUrlButtonToolTip.text());
+ this.btnCopy.addSelectionListener(new SelectionAdapter() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
+ * @since 0.6
+ */
+ @Override
+ public void widgetSelected( SelectionEvent e ) {
+ handleCopyUrl();
+ }
+ });
+
+ return panel;
+ }
+
+ /**
+ * @return the file system file this dialog is showing the published locations of (never <code>null</code>)
+ * @since 0.6
+ */
+ private File getFile() {
+ return this.file.getLocation().toFile();
+ }
+
+ /**
+ * This path does not include the name of the file.
+ *
+ * @return the path the file was published (never <code>null</code>)
+ * @since 0.6
+ */
+ private String getPath() {
+ return this.file.getParent().getFullPath().toString();
+ }
+
+ /**
+ * @param workspace the workspace where the file was published
+ * @return the URL where the file was published
+ * @since 0.6
+ */
+ String getPublishedAtUrl( Workspace workspace ) {
+ try {
+ return this.serverManager.getUrl(getFile(), getPath(), workspace).toString();
+ } catch (Exception e) {
+ String message = RestClientI18n.publishedLocationsDialogErrorObtainingUrlMsg.text();
+ Activator.getDefault().log(new Status(Severity.ERROR, message, e));
+ return message;
+ }
+
+ }
+
+ /**
+ * @return the workspaces the file has been published to (never <code>null</code>)
+ * @since 0.6
+ */
+ Object[] getWorkspaces() {
+ return this.workspaces.toArray();
+ }
+
+ /**
+ * Handler for when the copy URL button is clicked.
+ *
+ * @since 0.6
+ */
+ void handleCopyUrl() {
+ Workspace workspace = (Workspace)((IStructuredSelection)this.viewer.getSelection()).getFirstElement();
+ String url = getPublishedAtUrl(workspace);
+ Clipboard clipboard = new Clipboard(Display.getCurrent());
+ clipboard.setContents(new Object[] {url}, new Transfer[] {TextTransfer.getInstance()});
+ }
+
+ /**
+ * Handler for when a table row is selected.
+ *
+ * @since 0.6
+ */
+ void handleTableSelection() {
+ IStructuredSelection selection = (IStructuredSelection)this.viewer.getSelection();
+ boolean enable = (selection.size() == 1);
+
+ if (this.btnCopy.getEnabled() != enable) {
+ this.btnCopy.setEnabled(enable);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.dialogs.Dialog#initializeBounds()
+ * @since 0.6
+ */
+ @Override
+ protected void initializeBounds() {
+ super.initializeBounds();
+ Utils.centerAndSizeShellRelativeToDisplay(getShell(), 75, 75);
+ }
+
+ // ===========================================================================================================================
+ // Inner Class
+ // ===========================================================================================================================
+
+ /**
+ * The <code>LocationsTableProvider</code> provides content, labels, and images for the table.
+ *
+ * @since 0.6
+ */
+ class LocationsTableProvider implements IStructuredContentProvider, ITableLabelProvider {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ * @since 0.6
+ */
+ @Override
+ public void addListener( ILabelProviderListener listener ) {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#dispose()
+ * @since 0.6
+ */
+ @Override
+ public void dispose() {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnImage(java.lang.Object, int)
+ * @since 0.6
+ */
+ @Override
+ public Image getColumnImage( Object element,
+ int columnIndex ) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITableLabelProvider#getColumnText(java.lang.Object, int)
+ * @since 0.6
+ */
+ @Override
+ public String getColumnText( Object element,
+ int columnIndex ) {
+ Workspace workspace = (Workspace)element;
+
+ if (columnIndex == SERVER_URL_COL) {
+ return workspace.getServer().getUrl();
+ }
+
+ if (columnIndex == USER_COL) {
+ return workspace.getServer().getUser();
+ }
+
+ if (columnIndex == REPOSITORY_COL) {
+ return workspace.getRepository().getName();
+ }
+
+ if (columnIndex == WORKSPACE_COL) {
+ return workspace.getName();
+ }
+
+ if (columnIndex == FILE_URL_COL) {
+ return getPublishedAtUrl(workspace);
+ }
+
+ // should never get here
+ assert false;
+ return ""; //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Object[] getElements( Object inputElement ) {
+ return getWorkspaces();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object,
+ * java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public void inputChanged( Viewer viewer,
+ Object oldInput,
+ Object newInput ) {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
+ * @since 0.6
+ */
+ @Override
+ public boolean isLabelProperty( Object element,
+ String property ) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ * @since 0.6
+ */
+ @Override
+ public void removeListener( ILabelProviderListener listener ) {
+ // nothing to do
+ }
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/dialogs/PublishedLocationsDialog.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Copied: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaContentProvider.java (from rev 1171, branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/ServerContentProvider.java)
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaContentProvider.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaContentProvider.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -0,0 +1,355 @@
+/*
+ * 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.views;
+
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.PUBLISHED_OVERLAY_IMAGE;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ILightweightLabelDecorator;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.LabelProviderChangedEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IDecoratorManager;
+import org.jboss.dna.web.jcr.rest.client.ServerManager;
+import org.jboss.dna.web.jcr.rest.client.Status;
+import org.jboss.dna.web.jcr.rest.client.Status.Severity;
+import org.jboss.dna.web.jcr.rest.client.domain.IDnaObject;
+import org.jboss.dna.web.jcr.rest.client.domain.Repository;
+import org.jboss.dna.web.jcr.rest.client.domain.Server;
+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.DnaResourceHelper;
+import org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n;
+import org.jboss.dna.web.jcr.rest.client.swt.Utils;
+
+/**
+ * The <code>DnaContentProvider</code> is a content and label provider for DNA repositories.
+ *
+ * @since 0.6
+ */
+public final class DnaContentProvider extends ColumnLabelProvider implements ILightweightLabelDecorator, ITreeContentProvider {
+
+ // ===========================================================================================================================
+ // Constants
+ // ===========================================================================================================================
+
+ /**
+ * The decorator ID.
+ *
+ * @since 0.6
+ */
+ private static final String ID = "org.jboss.dna.web.jcr.rest.client.swt.dnaDecorator"; //$NON-NLS-1$
+
+ // ===========================================================================================================================
+ // Class Methods
+ // ===========================================================================================================================
+
+ /**
+ * @return the DNA decorator
+ * @since 0.6
+ */
+ public static DnaContentProvider getDecorator() {
+ IDecoratorManager decoratorMgr = Activator.getDefault().getWorkbench().getDecoratorManager();
+
+ if (decoratorMgr.getEnabled(ID)) {
+ return (DnaContentProvider)decoratorMgr.getBaseLabelProvider(ID);
+ }
+
+ return null;
+ }
+
+ // ===========================================dnaDecorator================================================================================
+ // Fields
+ // ===========================================================================================================================
+
+ /**
+ * The server manager where the server registry is managed.
+ *
+ * @since 0.6
+ */
+ private ServerManager serverManager;
+
+ // ===========================================================================================================================
+ // Methods
+ // ===========================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ * @since 0.6
+ */
+ @Override
+ public void addListener( ILabelProviderListener listener ) {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object, org.eclipse.jface.viewers.IDecoration)
+ * @since 0.6
+ */
+ @Override
+ public void decorate( final Object element,
+ IDecoration decoration ) {
+ ImageDescriptor overlay = null;
+ final Display display = Display.getDefault();
+
+ if (display.isDisposed()) {
+ return;
+ }
+
+ // must be an IDnaObject
+ if (getServerManager() != null) {
+ if (element instanceof Server) {
+ Status status = getServerManager().ping((Server)element);
+ overlay = Utils.getOverlayImage(status);
+ } else if ((element instanceof IFile) && new DnaResourceHelper(getServerManager()).isPublished((IFile)element)) {
+ overlay = Activator.getDefault().getImageDescriptor(PUBLISHED_OVERLAY_IMAGE);
+ }
+
+ if (overlay != null) {
+ decoration.addOverlay(overlay);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+ * @since 0.6
+ */
+ @Override
+ public void dispose() {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Object[] getChildren( Object parentElement ) {
+ assert (parentElement instanceof IDnaObject);
+
+ try {
+ if ((parentElement instanceof Server) && (getServerManager() != null)) {
+ 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));
+ }
+
+ try {
+ if ((parentElement instanceof Repository) && (getServerManager() != null)) {
+ return getServerManager().getWorkspaces((Repository)parentElement).toArray();
+ }
+ } catch (Exception e) {
+ String msg = RestClientI18n.serverManagerGetWorkspacesExceptionMsg.text();
+ Activator.getDefault().log(new Status(Severity.ERROR, msg, e));
+ }
+
+ return new Object[0];
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Object[] getElements( Object inputElement ) {
+ return ((getServerManager() == null) ? new Object[0] : getServerManager().getServers().toArray());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Image getImage( Object element ) {
+ return Activator.getDefault().getImage(element);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Object getParent( Object element ) {
+ assert (element instanceof IDnaObject);
+
+ if (element instanceof Workspace) {
+ return ((Workspace)element).getRepository();
+ }
+
+ if (element instanceof Repository) {
+ return ((Repository)element).getServer();
+ }
+
+ // server
+ return null;
+ }
+
+ /**
+ * @return the server manager or <code>null</code>
+ * @since 0.6
+ */
+ private ServerManager getServerManager() {
+ if (this.serverManager == null) {
+ this.serverManager = Activator.getDefault().getServerManager();
+ }
+
+ return this.serverManager;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public String getText( Object element ) {
+ assert (element instanceof IDnaObject);
+ return ((IDnaObject)element).getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipImage(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public Image getToolTipImage( Object object ) {
+ return getImage(object);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipText(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public String getToolTipText( Object element ) {
+ if (element instanceof IDnaObject) {
+ return ((IDnaObject)element).getShortDescription();
+ }
+
+ return super.getToolTipText(element);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipTimeDisplayed(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public int getToolTipTimeDisplayed( Object object ) {
+ return 3000;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public boolean hasChildren( Object element ) {
+ return getChildren(element).length > 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object,
+ * java.lang.Object)
+ * @since 0.6
+ */
+ @Override
+ public void inputChanged( Viewer viewer,
+ Object oldInput,
+ Object newInput ) {
+ // this.viewer = (StructuredViewer)viewer;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
+ * @since 0.6
+ */
+ @Override
+ public boolean isLabelProperty( Object element,
+ String property ) {
+ return false;
+ }
+
+ public void refresh( final Object element ) {
+ final Display display = Display.getDefault();
+
+ if (display.isDisposed()) {
+ return;
+ }
+
+ display.asyncExec(new Runnable() {
+ @SuppressWarnings( "synthetic-access" )
+ @Override
+ public void run() {
+ fireLabelProviderChanged(new LabelProviderChangedEvent(DnaContentProvider.this, element));
+ }
+ });
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
+ * @since 0.6
+ */
+ @Override
+ public void removeListener( ILabelProviderListener listener ) {
+ // nothing to do
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaContentProvider.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/views/DnaMessageConsole.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaMessageConsole.java (rev 0)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaMessageConsole.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -0,0 +1,359 @@
+/*
+ * 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.views;
+
+import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.DNA_IMAGE_16x;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.debug.ui.console.FileLink;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.FindReplaceDocumentAdapter;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentListener;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.console.ConsolePlugin;
+import org.eclipse.ui.console.IConsole;
+import org.eclipse.ui.console.IConsoleManager;
+import org.eclipse.ui.console.MessageConsole;
+import org.eclipse.ui.console.MessageConsoleStream;
+import org.jboss.dna.common.util.CheckArg;
+import org.jboss.dna.web.jcr.rest.client.Status;
+import org.jboss.dna.web.jcr.rest.client.Status.Severity;
+import org.jboss.dna.web.jcr.rest.client.swt.Activator;
+import org.jboss.dna.web.jcr.rest.client.swt.RestClientI18n;
+
+/**
+ * The <code>DnaMessageConsole</code> is a message console view where status of publishing operations are logged. This class
+ * ensures all writes to the console are done in the UI thread.
+ *
+ * @since 0.6
+ */
+public final class DnaMessageConsole extends MessageConsole {
+
+ // =======================================================================================================================
+ // Constants
+ // =======================================================================================================================
+
+ /**
+ * The identifier and type of the DNA Message Console.
+ *
+ * @since 0.6
+ */
+ private static final String ID = "org.jboss.dna.web.jcr.rest.client.swt.views.DnaMessageConsole"; //$NON-NLS-1$
+
+ /**
+ * The message console name.
+ *
+ * @since 0.6
+ */
+ private static final String NAME = RestClientI18n.dnaConsoleName.text();
+
+ // =======================================================================================================================
+ // Class Methods
+ // =======================================================================================================================
+
+ /**
+ * Note: The <code>DnaMessageConsole</code> should <strong>NOT</strong> be cached as the user can open/close/create instances.
+ *
+ * @return the DNA Message Console if available or a new one (never <code>null</code>)
+ * @since 0.6
+ */
+ private static DnaMessageConsole getDnaConsole() {
+ DnaMessageConsole console = null;
+ IConsoleManager consoleMgr = ConsolePlugin.getDefault().getConsoleManager();
+ IConsole[] consoles = consoleMgr.getConsoles();
+
+ // see if DNA console is open
+ for (int i = 0; i < consoles.length; ++i) {
+ if (NAME.equals(consoles[i].getName())) {
+ console = (DnaMessageConsole)consoles[i];
+ break;
+ }
+ }
+
+ // create DNA console if necessary
+ if (console == null) {
+ console = new DnaMessageConsole();
+ consoleMgr.addConsoles(new IConsole[] {console});
+ }
+
+ return console;
+ }
+
+ /**
+ * @param message the message being written to the console (never <code>null</code>)
+ * @param emphasize indicates if the message should be emphasized in the console
+ * @since 0.6
+ */
+ public static void write( String message,
+ boolean emphasize ) {
+ CheckArg.isNotNull(message, "message"); //$NON-NLS-1$
+ DnaMessageConsole console = getDnaConsole();
+ console.print(message, emphasize, false, null);
+ }
+
+ /**
+ * @param message the message being written to the console
+ * @param file the file whose full path, which is contained in the message, will be made into a hyperlink (may be
+ * <code>null</code>)
+ * @since 0.6
+ */
+ public static void write( String message,
+ IFile file ) {
+ CheckArg.isNotNull(message, "message"); //$NON-NLS-1$
+
+ DnaMessageConsole console = getDnaConsole();
+ console.print(message, false, false, file);
+ }
+
+ /**
+ * Adds a line feed to the console after the message is printed.
+ *
+ * @param message the message being written to the console (never <code>null</code>)
+ * @since 0.6
+ */
+ public static void writeln( String message ) {
+ CheckArg.isNotNull(message, "message"); //$NON-NLS-1$
+ writeln(message, null);
+ }
+
+ /**
+ * Adds a line feed to the console after the message is printed.
+ *
+ * @param message the message being written to the console (never <code>null</code>)
+ * @param file the file whose full path, which is contained in the message, will be made into a hyperlink (may be
+ * <code>null</code>)
+ * @since 0.6
+ */
+ public static void writeln( String message,
+ IFile file ) {
+ CheckArg.isNotNull(message, "message"); //$NON-NLS-1$
+
+ DnaMessageConsole console = getDnaConsole();
+ console.print(message, false, true, file);
+ }
+
+ // =======================================================================================================================
+ // Constructors
+ // =======================================================================================================================
+
+ /**
+ * @since 0.6
+ */
+ private DnaMessageConsole() {
+ super(NAME, Activator.getDefault().getImageDescriptor(DNA_IMAGE_16x));
+ }
+
+ // =======================================================================================================================
+ // Methods
+ // =======================================================================================================================
+
+ /**
+ * @param message the message being searched for
+ * @param file the file whose full path appears in the message and will become a hyperlink
+ * @since 0.6
+ */
+ void addDocumentListener( String message,
+ IFile file ) {
+ getDocument().addDocumentListener(new HyperlinkCreator(message, this, file));
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.console.AbstractConsole#getType()
+ * @since 0.6
+ */
+ @Override
+ public String getType() {
+ return ID;
+ }
+
+ /**
+ * @param message the message being written to the console (never <code>null</code>)
+ * @param emphasize a flag indicating if the message should be emphasized
+ * @param doLineFeedAtEnd a flag indicating if a line feed should be done after writing the message
+ * @param file the file to create a hyperlink for (may be <code>null</code>)
+ * @since 0.6
+ */
+ private void print( final String message,
+ final boolean emphasize,
+ final boolean doLineFeedAtEnd,
+ final IFile file ) {
+ final Display display = Display.getDefault();
+
+ if (!display.isDisposed()) {
+ display.asyncExec(new Runnable() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see java.lang.Runnable#run()
+ * @since 0.6
+ */
+ @Override
+ public void run() {
+ if (!display.isDisposed()) {
+ MessageConsoleStream stream = setup();
+
+ // configure stream
+ if (emphasize) {
+ stream.setColor(display.getSystemColor(SWT.COLOR_BLUE));
+ }
+
+ // register document listener before writing to console
+ if (file != null) {
+ addDocumentListener(message, file);
+ }
+
+ // write message
+ if (doLineFeedAtEnd) {
+ stream.println(message);
+ } else {
+ stream.print(message);
+ }
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Performs any setup required before writing to the console.
+ *
+ * @return the stream that can be written to
+ * @since 0.6
+ */
+ MessageConsoleStream setup() {
+ activate(); // show and focus console view
+ return newMessageStream();
+ }
+
+ // ===========================================================================================================================
+ // Inner Class
+ // ===========================================================================================================================
+
+ /**
+ * The <code>HyperlinkCreator</code> creates a hyperlink in a DNA Message Console for the first occurrence of the full path of
+ * a specified file.
+ *
+ * @since 0.6
+ */
+ class HyperlinkCreator implements IDocumentListener {
+
+ // =======================================================================================================================
+ // Fields
+ // =======================================================================================================================
+
+ /**
+ * The console where the message is printed to and the hyperlink will be created.
+ *
+ * @since 0.6
+ */
+ private final DnaMessageConsole console;
+
+ /**
+ * The file whose full path will become a hyperlink.
+ *
+ * @since 0.6
+ */
+ private final IFile file;
+
+ /**
+ * The message where the file path is located in.
+ *
+ * @since 0.6
+ */
+ private final String message;
+
+ // =======================================================================================================================
+ // Constructors
+ // =======================================================================================================================
+
+ /**
+ * @param message the message that contains the full path of the file
+ * @param console the console where the message appears
+ * @param file the file whose full path appears in the message and will become a hyperlink
+ * @since 0.6
+ */
+ public HyperlinkCreator( String message,
+ DnaMessageConsole console,
+ IFile file ) {
+ this.message = message;
+ this.console = console;
+ this.file = file;
+ }
+
+ // =======================================================================================================================
+ // Methods
+ // =======================================================================================================================
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.text.IDocumentListener#documentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
+ * @since 0.6
+ */
+ @Override
+ public void documentAboutToBeChanged( DocumentEvent arg0 ) {
+ // nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.jface.text.IDocumentListener#documentChanged(org.eclipse.jface.text.DocumentEvent)
+ * @since 0.6
+ */
+ @Override
+ public void documentChanged( DocumentEvent event ) {
+ IDocument document = event.getDocument();
+
+ try {
+ FindReplaceDocumentAdapter finder = new FindReplaceDocumentAdapter(document);
+ IRegion region = finder.find(document.getLength() - 1, this.message, false, true, false, false);
+
+ if (region != null) {
+ String target = this.file.getFullPath().toString();
+ int index = this.message.indexOf(target);
+
+ if (index == -1) {
+ throw new BadLocationException(RestClientI18n.dnaConsoleFilePathNotFoundMsg.text(target));
+ }
+
+ this.console.addHyperlink(new FileLink(file, null, -1, -1, -1), region.getOffset() + 1, target.length());
+
+ // created hyperlink so no need to listen any longer
+ document.removeDocumentListener(this);
+ }
+ } catch (BadLocationException e) {
+ Activator.getDefault().log(new Status(Severity.ERROR,
+ RestClientI18n.dnaConsoleProblemCreatingHyperlinkMsg.text(), e));
+ document.removeDocumentListener(this);
+ }
+ }
+ }
+
+}
Property changes on: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/DnaMessageConsole.java
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Deleted: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/ServerContentProvider.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/ServerContentProvider.java 2009-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/ServerContentProvider.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -1,317 +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.web.jcr.rest.client.swt.views;
-
-import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.PUBLISHED_OVERLAY_IMAGE;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.jface.resource.ImageDescriptor;
-import org.eclipse.jface.viewers.ColumnLabelProvider;
-import org.eclipse.jface.viewers.IDecoration;
-import org.eclipse.jface.viewers.ILabelProviderListener;
-import org.eclipse.jface.viewers.ILightweightLabelDecorator;
-import org.eclipse.jface.viewers.ITreeContentProvider;
-import org.eclipse.jface.viewers.LabelProviderChangedEvent;
-import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.swt.graphics.Image;
-import org.eclipse.swt.widgets.Display;
-import org.jboss.dna.web.jcr.rest.client.ServerManager;
-import org.jboss.dna.web.jcr.rest.client.Status;
-import org.jboss.dna.web.jcr.rest.client.Status.Severity;
-import org.jboss.dna.web.jcr.rest.client.domain.IDnaObject;
-import org.jboss.dna.web.jcr.rest.client.domain.Repository;
-import org.jboss.dna.web.jcr.rest.client.domain.Server;
-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;
-
-/**
- * The <code>ServerContentProvider</code> is a content and label provider for DNA repositories.
- *
- * @since 0.6
- */
-public final class ServerContentProvider extends ColumnLabelProvider implements ILightweightLabelDecorator, ITreeContentProvider {
-
- // ===========================================================================================================================
- // Fields
- // ===========================================================================================================================
-
- /**
- * The server manager where the server registry is managed.
- *
- * @since 0.6
- */
- private final ServerManager serverManager;
-
- // ===========================================================================================================================
- // Constructors
- // ===========================================================================================================================
-
- /**
- * @since 0.6
- */
- public ServerContentProvider() {
- this.serverManager = Activator.getDefault().getServerManager();
- }
-
- // ===========================================================================================================================
- // Methods
- // ===========================================================================================================================
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IBaseLabelProvider#addListener(org.eclipse.jface.viewers.ILabelProviderListener)
- * @since 0.6
- */
- @Override
- public void addListener( ILabelProviderListener listener ) {
- // nothing to do
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ILightweightLabelDecorator#decorate(java.lang.Object, org.eclipse.jface.viewers.IDecoration)
- * @since 0.6
- */
- @Override
- public void decorate( final Object element,
- IDecoration decoration ) {
- ImageDescriptor overlay = null;
- final Display display = Display.getDefault();
-
- if (display.isDisposed()) {
- return;
- }
-
- // must be an IDnaObject
- if (element instanceof Server) {
- Status status = Activator.getDefault().getServerManager().ping((Server)element);
- overlay = Utils.getOverlayImage(status);
- } else if (element instanceof IFile) {
- if (Utils.isPublished((IFile)element)) {
- overlay = Activator.getDefault().getImageDescriptor(PUBLISHED_OVERLAY_IMAGE);
- }
- }
-
- if (overlay != null) {
- decoration.addOverlay(overlay);
- }
-
- display.asyncExec(new Runnable() {
- @SuppressWarnings( "synthetic-access" )
- @Override
- public void run() {
- if (!display.isDisposed()) {
- fireLabelProviderChanged(new LabelProviderChangedEvent(ServerContentProvider.this, element));
- }
- }
- });
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IContentProvider#dispose()
- * @since 0.6
- */
- @Override
- public void dispose() {
- // nothing to do
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
- * @since 0.6
- */
- @Override
- public Object[] getChildren( Object parentElement ) {
- assert (parentElement instanceof IDnaObject);
-
- try {
- if (parentElement instanceof Server) {
- return this.serverManager.getRepositories((Server)parentElement).toArray();
- }
- } 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) {
- return this.serverManager.getWorkspaces((Repository)parentElement).toArray();
- }
- } catch (Exception e) {
- String msg = RestClientI18n.serverManagerGetWorkspacesExceptionMsg.text();
- Activator.getDefault().log(new Status(Severity.ERROR, msg, e));
- }
-
- return new Object[0];
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
- * @since 0.6
- */
- @Override
- public Object[] getElements( Object inputElement ) {
- return this.serverManager.getServers().toArray();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
- * @since 0.6
- */
- @Override
- public Image getImage( Object element ) {
- return Activator.getDefault().getImage(element);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
- * @since 0.6
- */
- @Override
- public Object getParent( Object element ) {
- assert (element instanceof IDnaObject);
-
- if (element instanceof Workspace) {
- return ((Workspace)element).getRepository();
- }
-
- if (element instanceof Repository) {
- return ((Repository)element).getServer();
- }
-
- // server
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
- * @since 0.6
- */
- @Override
- public String getText( Object element ) {
- assert (element instanceof IDnaObject);
- return ((IDnaObject)element).getName();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipImage(java.lang.Object)
- * @since 0.6
- */
- @Override
- public Image getToolTipImage( Object object ) {
- return getImage(object);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipText(java.lang.Object)
- * @since 0.6
- */
- @Override
- public String getToolTipText( Object element ) {
- if (element instanceof IDnaObject) {
- return ((IDnaObject)element).getShortDescription();
- }
-
- return super.getToolTipText(element);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.CellLabelProvider#getToolTipTimeDisplayed(java.lang.Object)
- * @since 0.6
- */
- @Override
- public int getToolTipTimeDisplayed( Object object ) {
- return 3000;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
- * @since 0.6
- */
- @Override
- public boolean hasChildren( Object element ) {
- return getChildren(element).length > 0;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object,
- * java.lang.Object)
- * @since 0.6
- */
- @Override
- public void inputChanged( Viewer viewer,
- Object oldInput,
- Object newInput ) {
- // nothing to do
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IBaseLabelProvider#isLabelProperty(java.lang.Object, java.lang.String)
- * @since 0.6
- */
- @Override
- public boolean isLabelProperty( Object element,
- String property ) {
- return false;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.jface.viewers.IBaseLabelProvider#removeListener(org.eclipse.jface.viewers.ILabelProviderListener)
- * @since 0.6
- */
- @Override
- public void removeListener( ILabelProviderListener listener ) {
- // nothing to do
- }
-
-}
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/ServerView.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/ServerView.java 2009-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/views/ServerView.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -24,7 +24,6 @@
package org.jboss.dna.web.jcr.rest.client.swt.views;
import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.COLLAPSE_ALL_IMAGE;
-import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.REFRESH_IMAGE;
import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.SERVER_VIEW_HELP_CONTEXT;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
@@ -55,6 +54,7 @@
import org.jboss.dna.web.jcr.rest.client.swt.actions.DeleteServerAction;
import org.jboss.dna.web.jcr.rest.client.swt.actions.EditServerAction;
import org.jboss.dna.web.jcr.rest.client.swt.actions.NewServerAction;
+import org.jboss.dna.web.jcr.rest.client.swt.actions.ReconnectToServerAction;
/**
* The <code>ServerView</code> shows all defined servers and their DNA repositories.
@@ -100,14 +100,14 @@
*
* @since 0.6
*/
- private ServerContentProvider provider;
+ private DnaContentProvider provider;
/**
- * Refreshes the tree.
+ * Refreshes the server connections.
*
* @since 0.6
*/
- private IAction refreshAction;
+ private ReconnectToServerAction reconnectAction;
/**
* @since 0.6
@@ -134,22 +134,9 @@
this.collapseAllAction.setImageDescriptor(Activator.getDefault().getImageDescriptor(COLLAPSE_ALL_IMAGE));
// the refresh action is always enabled
- this.refreshAction = new Action() {
- @Override
- public void run() {
- IStructuredSelection selection = (IStructuredSelection)getViewer().getSelection();
-
- if (selection.size() == 1) {
- getViewer().refresh(selection.getFirstElement());
- } else {
- getViewer().refresh();
- }
- }
- };
+ this.reconnectAction = new ReconnectToServerAction(this.viewer);
+ getServerManager().addRegistryListener(this.reconnectAction);
- this.refreshAction.setToolTipText(RestClientI18n.refreshActionToolTip.text());
- this.refreshAction.setImageDescriptor(Activator.getDefault().getImageDescriptor(REFRESH_IMAGE));
-
// the shell used for dialogs that the actions display
Shell shell = this.getSite().getShell();
@@ -174,7 +161,7 @@
menuMgr.add(this.newAction);
menuMgr.add(this.editAction);
menuMgr.add(this.deleteAction);
- // menuMgr.setRemoveAllWhenShown(true);
+ menuMgr.add(this.reconnectAction);
Menu menu = menuMgr.createContextMenu(this.viewer.getTree());
this.viewer.getTree().setMenu(menu);
@@ -189,7 +176,7 @@
toolBar.add(this.newAction);
toolBar.add(this.editAction);
toolBar.add(this.deleteAction);
- toolBar.add(this.refreshAction);
+ toolBar.add(this.reconnectAction);
toolBar.add(this.collapseAllAction);
}
@@ -198,7 +185,7 @@
* @since 0.6
*/
private void constructTreeViewer( Composite parent ) {
- this.provider = new ServerContentProvider();
+ this.provider = new DnaContentProvider();
this.viewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI);
this.viewer.setContentProvider(this.provider);
Modified: branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishJob.java
===================================================================
--- branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishJob.java 2009-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishJob.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -23,36 +23,25 @@
*/
package org.jboss.dna.web.jcr.rest.client.swt.wizards;
-import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.DNA_CONSOLE_ID;
import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.DNA_PUBLISHING_JOB_FAMILY;
import static org.jboss.dna.web.jcr.rest.client.swt.IUiConstants.PLUGIN_ID;
import java.io.File;
+import java.net.URL;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.debug.ui.console.FileLink;
-import org.eclipse.jface.text.BadLocationException;
-import org.eclipse.jface.text.DocumentEvent;
-import org.eclipse.jface.text.FindReplaceDocumentAdapter;
-import org.eclipse.jface.text.IDocument;
-import org.eclipse.jface.text.IDocumentListener;
-import org.eclipse.jface.text.IRegion;
-import org.eclipse.ui.console.ConsolePlugin;
-import org.eclipse.ui.console.IConsole;
-import org.eclipse.ui.console.IConsoleManager;
-import org.eclipse.ui.console.MessageConsole;
-import org.eclipse.ui.console.MessageConsoleStream;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.web.jcr.rest.client.ServerManager;
import org.jboss.dna.web.jcr.rest.client.Status;
-import org.jboss.dna.web.jcr.rest.client.Status.Severity;
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.DnaResourceHelper;
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.views.DnaContentProvider;
+import org.jboss.dna.web.jcr.rest.client.swt.views.DnaMessageConsole;
/**
* The <code>PublishJob</code> publishes or unpublishes one or more files using the {@link ServerManager}.
@@ -87,13 +76,6 @@
}
/**
- * The name of the message console that is written to.
- *
- * @since 0.6
- */
- static final String CONSOLE_NAME = RestClientI18n.publishJobConsoleName.text();
-
- /**
* A unique job identifier given to each publishing/unpublishing job.
*
* @since 0.6
@@ -106,18 +88,20 @@
/**
* @param type the job type (never <code>null</code>)
+ * @param jobId the job identifier
* @return the job name
* @since 0.6
*/
- private static String getJobName( Type type ) {
+ private static String getJobName( Type type,
+ int jobId ) {
CheckArg.isNotNull(type, "type"); //$NON-NLS-1$
if (Type.PUBLISH == type) {
- return RestClientI18n.publishJobPublishName.text();
+ return RestClientI18n.publishJobPublishName.text(jobId);
}
// unpublish
- return RestClientI18n.publishJobUnpublishName.text();
+ return RestClientI18n.publishJobUnpublishName.text(jobId);
}
// ===========================================================================================================================
@@ -132,6 +116,13 @@
private final List<IFile> files;
/**
+ * The unique job identifier.
+ *
+ * @since 0.6
+ */
+ private final int jobId;
+
+ /**
* The job type.
*
* @since 0.6
@@ -158,13 +149,14 @@
public PublishJob( Type type,
List<IFile> files,
Workspace workspace ) {
- super(getJobName(type));
+ super(getJobName(type, JOB_ID.incrementAndGet()));
CheckArg.isNotNull(files, "files"); //$NON-NLS-1$
this.type = type;
this.files = files;
this.workspace = workspace;
+ this.jobId = JOB_ID.get();
setUser(true); // allow user to run in background
}
@@ -185,31 +177,11 @@
}
/**
- * Note: The <code>DnaConsole</code> should <strong>NOT</strong> be cached as the user can open/close/create instances.
- *
- * @return the DNA Message Console if available or a new one
+ * @return the server manager
* @since 0.6
*/
- private DnaConsole getDnaConsole() {
- DnaConsole console = null;
- IConsoleManager consoleMgr = ConsolePlugin.getDefault().getConsoleManager();
- IConsole[] consoles = consoleMgr.getConsoles();
-
- // see if DNA console already exists
- for (int i = 0; i < consoles.length; ++i) {
- if (CONSOLE_NAME.equals(consoles[i].getName())) {
- console = (DnaConsole)consoles[i];
- break;
- }
- }
-
- // create DNA console if necessary
- if (console == null) {
- console = new DnaConsole();
- consoleMgr.addConsoles(new IConsole[] {console});
- }
-
- return console;
+ private ServerManager getServerManager() {
+ return Activator.getDefault().getServerManager();
}
/**
@@ -229,84 +201,99 @@
@Override
protected IStatus run( IProgressMonitor monitor ) {
assert (this.workspace != null);
- int jobId = JOB_ID.getAndIncrement();
long startTime = System.currentTimeMillis();
try {
- String name = (isPublishing() ? RestClientI18n.publishJobPublishTaskName.text() : RestClientI18n.publishJobUnpublishTaskName.text());
- monitor.beginTask(name, this.files.size());
+ int fileCount = this.files.size();
+ String name = (isPublishing() ? RestClientI18n.publishJobPublishTaskName.text(this.jobId)
+ : RestClientI18n.publishJobUnpublishTaskName.text(this.jobId));
+ monitor.beginTask(name, fileCount);
monitor.setTaskName(name);
+ String serverUrl = this.workspace.getServer().getUrl();
+ String repositoryName = this.workspace.getRepository().getName();
+ String workspaceName = this.workspace.getName();
+
// write initial message to console
if (isPublishing()) {
- writeToConsole(getDnaConsole(), RestClientI18n.publishJobPublish.text(jobId,
- this.workspace.getServer().getUrl(),
- this.workspace.getRepository().getName(),
- this.workspace.getName(),
- this.files.size()));
+ DnaMessageConsole.writeln(RestClientI18n.publishJobPublish.text(this.jobId,
+ serverUrl,
+ repositoryName,
+ workspaceName,
+ fileCount));
} else {
- writeToConsole(getDnaConsole(), RestClientI18n.publishJobUnpublish.text(jobId,
- this.workspace.getServer().getUrl(),
- this.workspace.getRepository().getName(),
- this.workspace.getName(),
- this.files.size()));
+ DnaMessageConsole.writeln(RestClientI18n.publishJobUnpublish.text(this.jobId,
+ serverUrl,
+ repositoryName,
+ workspaceName,
+ fileCount));
}
- // process the files
+ DnaResourceHelper resourceHelper = new DnaResourceHelper(getServerManager());
int numProcessed = 0;
+ // process the files
for (IFile eclipseFile : this.files) {
if (monitor.isCanceled()) {
- String msg = null;
-
if (isPublishing()) {
- msg = RestClientI18n.publishJobPublishCanceledMsg.text(jobId,
- this.workspace.getServer().getUrl(),
- this.workspace.getRepository().getName(),
- this.workspace.getName(),
- numProcessed,
- this.files.size());
+ DnaMessageConsole.writeln(RestClientI18n.publishJobPublishCanceledMsg.text(this.jobId,
+ serverUrl,
+ repositoryName,
+ workspaceName,
+ numProcessed,
+ fileCount));
} else {
- msg = RestClientI18n.publishJobUnpublishCanceledMsg.text(jobId,
- this.workspace.getServer().getUrl(),
- this.workspace.getRepository().getName(),
- this.workspace.getName(),
- numProcessed,
- this.files.size());
+ DnaMessageConsole.writeln(RestClientI18n.publishJobUnpublishCanceledMsg.text(this.jobId,
+ serverUrl,
+ repositoryName,
+ workspaceName,
+ numProcessed,
+ fileCount));
}
- writeToConsole(getDnaConsole(), msg); // write cancel msg to console
- throw new InterruptedException(msg);
+ throw new InterruptedException(RestClientI18n.publishJobCanceled.text(jobId));
}
File file = eclipseFile.getLocation().toFile();
+ String path = eclipseFile.getParent().getFullPath().toString();
Status status = null;
if (isPublishing()) {
- status = Activator.getDefault().getServerManager().publish(this.workspace,
- eclipseFile.getFullPath().toString(),
- file);
+ status = getServerManager().publish(this.workspace, path, file);
// set persistent property on resource indicating it has been published
if (!status.isError()) {
- Utils.addPublishedProperty(eclipseFile, workspace);
+ resourceHelper.addPublishedProperty(eclipseFile, workspace);
+ DnaContentProvider decorator = DnaContentProvider.getDecorator();
+
+ if (decorator != null) {
+ // decorator.refresh(eclipseFile);
+ }
}
} else {
- status = Activator.getDefault().getServerManager().unpublish(this.workspace,
- eclipseFile.getFullPath().toString(),
- file);
+ status = getServerManager().unpublish(this.workspace, path, file);
// clear persistent property on resource indicating it has been unpublished
if (!status.isError()) {
- Utils.removePublishedProperty(eclipseFile, workspace);
+ resourceHelper.removePublishedProperty(eclipseFile, workspace);
+ DnaContentProvider decorator = DnaContentProvider.getDecorator();
+
+ if (decorator != null) {
+ // decorator.refresh(eclipseFile);
+ }
}
}
++numProcessed;
monitor.worked(1);
- // write outcome msg to console
- writeToConsole(jobId, eclipseFile, status);
+ // write outcome message to console
+ if (isPublishing() && status.isOk()) {
+ URL url = getServerManager().getUrl(file, path, this.workspace);
+ writeToConsole(eclipseFile, url, status);
+ } else {
+ writeToConsole(eclipseFile, null, status);
+ }
}
return org.eclipse.core.runtime.Status.OK_STATUS;
@@ -323,158 +310,79 @@
} finally {
monitor.done();
- // add operation done msg
- // TODO need to format this duration better
- long duration = System.currentTimeMillis() - startTime;
+ // add operation completed message
+ String duration;
+ long milliseconds = (System.currentTimeMillis() - startTime);
+ long hours = milliseconds / (1000 * 60 * 60);
+ long minutes = (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
+ long seconds = ((milliseconds % (1000 * 60 * 60)) % (1000 * 60)) / 1000;
+ if ((seconds > 0) || (minutes > 0) || (hours > 0)) {
+ duration = RestClientI18n.publishJobLongDurationMsg.text(hours, minutes, seconds);
+ } else {
+ duration = RestClientI18n.publishJobShortDurationMsg.text();
+ }
+
if (isPublishing()) {
- writeToConsole(getDnaConsole(),
- RestClientI18n.publishJobPublishFinishedMsg.text(jobId,
- this.workspace.getServer().getUrl(),
- this.workspace.getRepository().getName(),
- this.workspace.getName(),
- duration));
+ DnaMessageConsole.writeln(RestClientI18n.publishJobPublishFinishedMsg.text(this.jobId, duration));
} else {
- writeToConsole(getDnaConsole(),
- RestClientI18n.publishJobUnpublishFinishedMsg.text(jobId,
- this.workspace.getServer().getUrl(),
- this.workspace.getRepository().getName(),
- this.workspace.getName(),
- duration));
+ DnaMessageConsole.writeln(RestClientI18n.publishJobUnpublishFinishedMsg.text(this.jobId, duration));
}
}
}
/**
- * @param jobId the job ID
+ * Create a hyperlink in console.
+ *
* @param file the file involved in the publishing operation
+ * @param url the destination file URL or <code>null</code>
* @param status the status of the publishing operation
* @since 0.6
*/
- private void writeToConsole( int jobId,
- final IFile file,
+ private void writeToConsole( final IFile file,
+ URL url,
Status status ) {
- String msg = null;
+ String message = null;
if (status.isOk()) {
if (isPublishing()) {
- msg = RestClientI18n.publishJobPublishFile.text(jobId, file.getFullPath());
+ DnaMessageConsole.write(RestClientI18n.publishJobPublishFile.text(this.jobId, file.getFullPath()), false);
+ DnaMessageConsole.write(RestClientI18n.publishJobPublishFile2.text(url.toString()), true);
+ message = ""; //$NON-NLS-1$
} else {
- msg = RestClientI18n.publishJobUnpublishFile.text(jobId, file.getFullPath());
+ message = RestClientI18n.publishJobUnpublishFile.text(this.jobId, file.getFullPath());
}
} else if (status.isError()) {
if (isPublishing()) {
- msg = RestClientI18n.publishJobPublishFileFailed.text(jobId, file.getFullPath());
+ message = RestClientI18n.publishJobPublishFileFailed.text(this.jobId, file.getFullPath());
} else {
- msg = RestClientI18n.publishJobUnpublishFileFailed.text(jobId, file.getFullPath());
+ message = RestClientI18n.publishJobUnpublishFileFailed.text(this.jobId, file.getFullPath());
}
// log
Activator.getDefault().log(status);
} else if (status.isWarning()) {
if (isPublishing()) {
- msg = RestClientI18n.publishJobPublishFileWarning.text(jobId, file.getFullPath());
+ message = RestClientI18n.publishJobPublishFileWarning.text(this.jobId, file.getFullPath());
} else {
- msg = RestClientI18n.publishJobUnpublishFileWarning.text(jobId, file.getFullPath());
+ message = RestClientI18n.publishJobUnpublishFileWarning.text(this.jobId, file.getFullPath());
}
// log
Activator.getDefault().log(status);
} else {
if (isPublishing()) {
- msg = RestClientI18n.publishJobPublishFileInfo.text(jobId, file.getFullPath());
+ message = RestClientI18n.publishJobPublishFileInfo.text(this.jobId, file.getFullPath());
} else {
- msg = RestClientI18n.publishJobUnpublishFileInfo.text(jobId, file.getFullPath());
+ message = RestClientI18n.publishJobUnpublishFileInfo.text(this.jobId, file.getFullPath());
}
// log
Activator.getDefault().log(status);
}
- // write to DNA Console
- final DnaConsole dnaConsole = getDnaConsole();
- final String consoleMsg = msg;
- final IDocument doc = dnaConsole.getDocument();
-
- // add listener that will add the hyperlink in the console for the file just published/unpublished
- doc.addDocumentListener(new IDocumentListener() {
- @Override
- public void documentAboutToBeChanged( DocumentEvent event ) {
- // nothing to do
- }
-
- @Override
- public void documentChanged( DocumentEvent event ) {
- try {
- // add hyperlink to console
- int startIndex = consoleMsg.indexOf('"');
-
- if (startIndex != -1) {
- ++startIndex; // move after the '""
- int lastIndex = consoleMsg.lastIndexOf('"');
-
- if (lastIndex != -1) {
- --lastIndex; // move before the '"'
- FindReplaceDocumentAdapter finder = new FindReplaceDocumentAdapter(doc);
- IRegion region = finder.find(0, consoleMsg, true, true, false, false);
-
- if (region != null) {
- dnaConsole.addHyperlink(new FileLink(file, null, -1, -1, -1),
- (region.getOffset() + startIndex),
- (lastIndex - startIndex + 1));
- doc.removeDocumentListener(this);
- }
- }
- }
- } catch (BadLocationException e) {
- Activator.getDefault().log(new Status(Severity.ERROR,
- RestClientI18n.publishJobProblemCreatingHyperlinkMsg.text(), e));
- doc.removeDocumentListener(this);
- }
- }
- });
-
- writeToConsole(dnaConsole, msg);
+ // write to console creating a hyperlink
+ DnaMessageConsole.writeln(message, file);
}
- /**
- * @param console the DNA console being written to
- * @param message the message being written
- * @since 0.6
- */
- private void writeToConsole( MessageConsole console,
- String message ) {
- // show and focus console view
- console.activate();
-
- // write message
- MessageConsoleStream out = console.newMessageStream();
- out.println(message);
- }
-
- // ===========================================================================================================================
- // Inner Class
- // ===========================================================================================================================
-
- class DnaConsole extends MessageConsole {
-
- /**
- * @since 0.6
- */
- public DnaConsole() {
- super(CONSOLE_NAME, null);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.ui.console.AbstractConsole#getType()
- * @since 0.6
- */
- @Override
- public String getType() {
- return DNA_CONSOLE_ID;
- }
- }
-
}
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-08-28 15:55:28 UTC (rev 1181)
+++ branches/eclipse/org.jboss.dna.publish.ui.swt/src/org/jboss/dna/web/jcr/rest/client/swt/wizards/PublishPage.java 2009-08-31 13:46:22 UTC (rev 1182)
@@ -430,9 +430,6 @@
btnNewServer.removeSelectionListener(this);
}
});
-
- // register to receive server registry events that will be generated when the new server dialog is run
- getServerManager().addRegistryListener(this);
}
{ // row 2: repository row
@@ -550,8 +547,8 @@
IWorkbenchHelpSystem helpSystem = Activator.getDefault().getWorkbench().getHelpSystem();
helpSystem.setHelp(pnlMain, PUBLISH_DIALOG_HELP_CONTEXT);
- // load the UI with data
- refreshServers();
+ // register to receive server registry events (this will populate the UI)
+ getServerManager().addRegistryListener(this);
}
/**
14 years, 8 months
DNA SVN: r1181 - in trunk: dna-jcr/src/main/java/org/jboss/dna/jcr and 1 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-08-28 11:55:28 -0400 (Fri, 28 Aug 2009)
New Revision: 1181
Modified:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.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
A user reported an NPE, which I wasn't able to reproduce, but I changed AbstractJcrNode.toString() to better handle this situation if it should arise. However, it shouldn't really be happening in the first place, so I've made a few other changes to try and further prevent this NPE.
First, the PropertyIterator should never expose a null Property, so the code that is creating this (and the underlying collection of Property objects) was changed to never add a null reference to the collection.
Second, the SVN connector had one case where it *might* add a null property object to the resulting nodes, so the code was changed to handle this case.
Modified: 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-08-28 15:26:27 UTC (rev 1180)
+++ trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java 2009-08-28 15:55:28 UTC (rev 1181)
@@ -83,10 +83,11 @@
@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().getPath());
+ System.out.println(nodeIterator.nextNode());
}
assertThat(this.session.getRootNode().getNode("dna-graph"), is(notNullValue()));
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-08-28 15:26:27 UTC (rev 1180)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-08-28 15:55:28 UTC (rev 1181)
@@ -1690,7 +1690,7 @@
StringBuffer propertyBuff = new StringBuffer();
while (iter.hasNext()) {
AbstractJcrProperty prop = (AbstractJcrProperty)iter.nextProperty();
- propertyBuff.append(prop.toString()).append(", ");
+ propertyBuff.append(prop).append(", ");
}
return this.getPath() + " {" + propertyBuff.toString() + "}";
} catch (RepositoryException re) {
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-08-28 15:26:27 UTC (rev 1180)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-08-28 15:55:28 UTC (rev 1181)
@@ -599,7 +599,8 @@
Name propertyName = property.getName();
if (propertyName.equals(JcrLexicon.UUID) && !isReferenceable(node)) continue;
if (!propertyName.getNamespaceUri().equals(DnaIntLexicon.Namespace.URI)) {
- result.add(property.getPayload().getJcrProperty());
+ AbstractJcrProperty prop = property.getPayload().getJcrProperty();
+ if (prop != null) result.add(prop);
}
}
return result;
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-08-28 15:26:27 UTC (rev 1180)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-08-28 15:55:28 UTC (rev 1181)
@@ -131,6 +131,15 @@
this.accessData = accessData;
}
+ protected void addProperty( List<Property> properties,
+ PropertyFactory factory,
+ Name propertyName,
+ Object value ) {
+ if (value != null) {
+ properties.add(factory.create(propertyName, value));
+ }
+ }
+
protected boolean readNode( String workspaceName,
Location myLocation,
List<Property> properties,
@@ -186,10 +195,10 @@
}
if (properties != null) {
// Load the properties for this directory ......
- properties.add(factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FOLDER));
+ addProperty(properties, factory, JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FOLDER);
SVNDirEntry entry = getEntryInfo(workspaceRoot, directoryPath);
if (entry != null) {
- properties.add(factory.create(JcrLexicon.LAST_MODIFIED, dateFactory.create(entry.getDate())));
+ addProperty(properties, factory, JcrLexicon.LAST_MODIFIED, dateFactory.create(entry.getDate()));
}
}
} else {
@@ -205,8 +214,8 @@
SVNDirEntry entry = getEntryInfo(workspaceRoot, contentPath);
if (entry != null) {
// The request is to get properties of the "jcr:content" child node ...
- properties.add(factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.RESOURCE));
- properties.add(factory.create(JcrLexicon.LAST_MODIFIED, dateFactory.create(entry.getDate())));
+ addProperty(properties, factory, JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.RESOURCE);
+ addProperty(properties, factory, JcrLexicon.LAST_MODIFIED, dateFactory.create(entry.getDate()));
}
ByteArrayOutputStream os = new ByteArrayOutputStream();
@@ -214,12 +223,12 @@
getData(contentPath, fileProperties, os);
String mimeType = fileProperties.getStringValue(SVNProperty.MIME_TYPE);
if (mimeType == null) mimeType = DEFAULT_MIME_TYPE;
- properties.add(factory.create(JcrLexicon.MIMETYPE, mimeType));
+ addProperty(properties, factory, JcrLexicon.MIMETYPE, mimeType);
if (os.toByteArray().length > 0) {
// Now put the file's content into the "jcr:data" property ...
BinaryFactory binaryFactory = getExecutionContext().getValueFactories().getBinaryFactory();
- properties.add(factory.create(JcrLexicon.DATA, binaryFactory.create(os.toByteArray())));
+ addProperty(properties, factory, JcrLexicon.DATA, binaryFactory.create(os.toByteArray()));
}
}
} else {
@@ -235,14 +244,12 @@
}
if (properties != null) {
// Now add the properties to "nt:file" ...
- properties.add(factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE));
+ addProperty(properties, factory, JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE);
ByteArrayOutputStream os = new ByteArrayOutputStream();
SVNProperties fileProperties = new SVNProperties();
getData(filePath, fileProperties, os);
String created = fileProperties.getStringValue(SVNProperty.COMMITTED_DATE);
- if (created != null) {
- properties.add(factory.create(JcrLexicon.CREATED, dateFactory.create(created)));
- }
+ addProperty(properties, factory, JcrLexicon.CREATED, dateFactory.create(created));
}
}
}
14 years, 8 months
DNA SVN: r1180 - in trunk: dna-graph/src/main/java/org/jboss/dna/graph/connector/map and 9 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-08-28 11:26:27 -0400 (Fri, 28 Aug 2009)
New Revision: 1180
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinMirrorRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneBranchRequest.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java
trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java
trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
Log:
DNA-508 Workspace move/clone referenceable nodes is failing
One of the problems was that the workspace move method implementation (down in GraphSession) was not changing the children (of the new and old parent) to reflect the newly removed/added children. The correction was simply a call to an existing method (similar to what was being done in copy).
The second problem was the fact that clone was not removing from the session state (again, down in GraphSession) the nodes that were being removed during the clone operation, and therefore the session state had nodes that no longer existed in the persistent store. Unfortunately, the set of nodes that were indeed removed as part of the clone operation was not available after the fact, so correcting this behavior required adding the Set<Location> of these deleted nodes into the CloneBranchRequest. This in turn mandated that all writable connector implementations be changed to set this information as part of the processing of these requests. Once this was done, the GraphSession could be changed to use this information to remove these nodes from its cache.
Incidentally, I discovered another possible error condition regarding clone. Consider a session node A, which has the same UUID as node B in another workspace. If that session attempts to clone node B (from the other workspace) and the clone method's removeExisting parameter is true, then node A needs to be removed in order for the clone to succeed. So far this is the normal situation. However, if node A has transient changes, then it cannot be removed from the session. Therefore, I changed the JcrWorkspace.clone(...) method to check for this case and throw a RepositoryException. (The spec did not delineate this error condition, so I'm assuming that this is the best type of exception to throw.) Luckily, the method was already checking that the would-be-deleted nodes were not mandatory, so also checking whether the node has local changes was very easy.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinMirrorRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinMirrorRequestProcessor.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinMirrorRequestProcessor.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -174,7 +174,8 @@
*/
@Override
public void process( ReadNextBlockOfChildrenRequest request ) {
- ReadNextBlockOfChildrenRequest source = (ReadNextBlockOfChildrenRequest)federatedRequest.getFirstProjectedRequest().getRequest();
+ ReadNextBlockOfChildrenRequest source = (ReadNextBlockOfChildrenRequest)federatedRequest.getFirstProjectedRequest()
+ .getRequest();
if (checkErrorOrCancel(request, source)) return;
request.setActualLocationOfStartingAfterNode(source.getActualLocationOfStartingAfterNode());
for (Location childInSource : source.getChildren()) {
@@ -324,6 +325,7 @@
CloneBranchRequest source = (CloneBranchRequest)federatedRequest.getFirstProjectedRequest().getRequest();
if (checkErrorOrCancel(request, source)) return;
request.setActualLocations(source.getActualLocationBefore(), source.getActualLocationAfter());
+ request.setRemovedNodes(source.getRemovedNodes());
}
/**
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/federation/JoinRequestProcessor.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -24,11 +24,14 @@
package org.jboss.dna.graph.connector.federation;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
+import java.util.Set;
import java.util.concurrent.BlockingQueue;
import net.jcip.annotations.NotThreadSafe;
import org.jboss.dna.graph.ExecutionContext;
@@ -768,7 +771,7 @@
* Project the supplied location in a source into its federated location. The projection is used to find the location under
* the supplied ancestor. Any errors are recorded on the original request.
*
- * @param ancestorInFederation the ancestor in the federated repository; may not be nul
+ * @param ancestorInFederation the ancestor in the federated repository; may not be null
* @param projection the projection that should be used; may not be null
* @param actualSourceLocation the actual location in the source that is to be projected back into the federated repository;
* may not be null
@@ -795,6 +798,31 @@
}
/**
+ * Project the supplied location in a source into its federated location. The projection is used to find the location under
+ * the supplied ancestor. Any errors are recorded on the original request.
+ *
+ * @param projection the projection that should be used; may not be null
+ * @param actualSourceLocation the actual location in the source that is to be projected back into the federated repository;
+ * may not be null
+ * @param originalRequest the original request, if there are errors; may not be null
+ * @return the location in the federated repository
+ */
+ protected Location projectToFederated( Projection projection,
+ Location actualSourceLocation,
+ Request originalRequest ) {
+ Path actualPathInSource = actualSourceLocation.getPath();
+ // Project the actual location ...
+ for (Path path : projection.getPathsInRepository(actualPathInSource, pathFactory)) {
+ return actualSourceLocation.with(path);
+ }
+ // Record that there was an error projecting the results ...
+ String whereInSource = actualSourceLocation.getString(getExecutionContext().getNamespaceRegistry());
+ String msg = GraphI18n.unableToProjectSourceInformationIntoWorkspace.text(whereInSource, getSourceName(), projection);
+ originalRequest.setError(new InvalidRequestException(msg));
+ return null;
+ }
+
+ /**
* {@inheritDoc}
*
* @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.CreateNodeRequest)
@@ -981,6 +1009,13 @@
locationBefore = projectToFederated(request.from(), projected.getProjection(), locationBefore, request);
locationAfter = projectToFederated(request.into(), projected.getSecondProjection(), locationAfter, request);
request.setActualLocations(locationBefore, locationAfter);
+ if (source.removeExisting()) {
+ Set<Location> removed = new HashSet<Location>();
+ for (Location location : request.getRemovedNodes()) {
+ removed.add(projectToFederated(projected.getSecondProjection(), location, request));
+ }
+ request.setRemovedNodes(Collections.unmodifiableSet(removed));
+ }
}
/**
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/AbstractMapWorkspace.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -34,6 +34,7 @@
import java.util.Set;
import java.util.UUID;
import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NamespaceRegistry;
@@ -357,13 +358,13 @@
assert this.getRoot().equals(node) != true;
MapNode oldParent = node.getParent();
Name oldName = node.getName().getName();
-
+
if (this.equals(newAbstractMapWorkspace) && node.getParent().getUuid().equals(newParent.getUuid())
&& node.equals(beforeNode)) {
// Trivial move of a node to its parent before itself
return;
}
-
+
if (oldParent != null) {
boolean removed = oldParent.getChildren().remove(node);
assert removed == true;
@@ -526,7 +527,7 @@
/**
* {@inheritDoc}
*
- * @see MapWorkspace#cloneNode(ExecutionContext, MapNode, MapWorkspace, MapNode, Name, Segment, boolean)
+ * @see MapWorkspace#cloneNode(ExecutionContext, MapNode, MapWorkspace, MapNode, Name, Segment, boolean, Set)
*/
public MapNode cloneNode( ExecutionContext context,
MapNode original,
@@ -534,7 +535,8 @@
MapNode newParent,
Name desiredName,
Segment desiredSegment,
- boolean removeExisting ) throws UuidAlreadyExistsException {
+ boolean removeExisting,
+ Set<Location> removedExistingNodes ) throws UuidAlreadyExistsException {
assert context != null;
assert original != null;
assert newWorkspace != null;
@@ -543,17 +545,23 @@
Set<UUID> uuidsInFromBranch = getUuidsUnderNode(original);
MapNode existing;
+ PathFactory pathFactory = context.getValueFactories().getPathFactory();
+
// TODO: Need to handle removing/throwing root node
if (removeExisting) {
-
+ // Remove all of the nodes that have a UUID from under the original node, but DO NOT yet remove
+ // a node that has the UUID of the original node (as this will be handled later) ...
for (UUID uuid : uuidsInFromBranch) {
if (null != (existing = newWorkspace.getNode(uuid))) {
newWorkspace.removeNode(context, existing);
+ if (removedExistingNodes != null) {
+ Path path = pathFor(pathFactory, existing);
+ removedExistingNodes.add(Location.create(path, uuid));
+ }
}
}
} else {
- PathFactory pathFactory = context.getValueFactories().getPathFactory();
- uuidsInFromBranch.add(original.getUuid());
+ uuidsInFromBranch.add(original.getUuid()); // uuidsInFromBranch does not include the UUID of the original
for (UUID uuid : uuidsInFromBranch) {
if (null != (existing = newWorkspace.getNode(uuid))) {
NamespaceRegistry namespaces = context.getNamespaceRegistry();
@@ -589,17 +597,21 @@
return newRoot;
}
+ // Now deal with an existing node that has the same UUID as the original node ...
existing = newWorkspace.getNode(original.getUuid());
-
if (existing != null) {
newWorkspace.removeNode(context, existing);
+ if (removedExistingNodes != null) {
+ Path path = pathFor(pathFactory, existing);
+ removedExistingNodes.add(Location.create(path, original.getUuid()));
+ }
}
return copyNode(context, original, newWorkspace, newParent, desiredName, true, (Map<UUID, UUID>)null);
}
/**
- * Returns all of the UUIDs in the branch rooted at {@code node}. The UUID of {@code node} will not be included in the set of
- * returned UUIDs.
+ * Returns all of the UUIDs in the branch rooted at {@code node}. The UUID of {@code node} <i>will</i> be included in the set
+ * of returned UUIDs.
*
* @param node the root of the branch
* @return all of the UUIDs in the branch rooted at {@code node}
@@ -607,7 +619,6 @@
public Set<UUID> getUuidsUnderNode( MapNode node ) {
Set<UUID> uuids = new HashSet<UUID>();
uuidsUnderNode(node, uuids);
-
return uuids;
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRepository.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -248,7 +248,7 @@
// Loop over each child and call this method to copy the immediate children (and below).
// Note that this makes the copy have the same UUID as the original.
for (MapNode originalNode : origRoot.getChildren()) {
- original.cloneNode(context, originalNode, workspace, root, originalNode.getName().getName(), null, true);
+ original.cloneNode(context, originalNode, workspace, root, originalNode.getName().getName(), null, true, null);
}
}
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapRequestProcessor.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -23,6 +23,7 @@
*/
package org.jboss.dna.graph.connector.map;
+import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -132,17 +133,20 @@
// Look up the new parent, which must exist ...
Path newParentPath = request.into().getPath();
MapNode newParent = newWorkspace.getNode(newParentPath);
+ Set<Location> removedExistingNodes = new HashSet<Location>();
MapNode newNode = workspace.cloneNode(getExecutionContext(),
node,
newWorkspace,
newParent,
request.desiredName(),
request.desiredSegment(),
- request.removeExisting());
+ request.removeExisting(),
+ removedExistingNodes);
Path newPath = getExecutionContext().getValueFactories().getPathFactory().create(newParentPath, newNode.getName());
Location oldLocation = getActualLocation(request.from(), node);
Location newLocation = Location.create(newPath, newNode.getUuid());
request.setActualLocations(oldLocation, newLocation);
+ request.setRemovedNodes(Collections.unmodifiableSet(removedExistingNodes));
recordChange(request);
}
@@ -278,6 +282,7 @@
MapNode beforeNode = request.before() != null ? getTargetNode(workspace, request, request.before()) : null;
MapNode node = getTargetNode(workspace, request, request.from());
if (node == null) return;
+ if (request.hasError()) return; // if beforeNode could not be found
// Look up the new parent, which must exist ...
Path newParentPath;
@@ -298,6 +303,12 @@
}
MapNode newParent = workspace.getNode(newParentPath);
+ if (newParent == null) {
+ Path lowestExisting = workspace.getLowestExistingPath(newParentPath);
+ request.setError(new PathNotFoundException(request.into(), lowestExisting,
+ GraphI18n.inMemoryNodeDoesNotExist.text(newParentPath)));
+ return;
+ }
workspace.moveNode(getExecutionContext(), node, request.desiredName(), workspace, newParent, beforeNode);
assert node.getParent() == newParent;
Path newPath = getExecutionContext().getValueFactories().getPathFactory().create(newParentPath, node.getName());
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/connector/map/MapWorkspace.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -23,8 +23,10 @@
*/
package org.jboss.dna.graph.connector.map;
+import java.util.Set;
import java.util.UUID;
import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Location;
import org.jboss.dna.graph.connector.UuidAlreadyExistsException;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.Path;
@@ -162,6 +164,8 @@
* @param removeExisting true if existing nodes in the new workspace with the same UUIDs as nodes in the branch rooted at
* {@code original} should be removed; if false, a UuidAlreadyExistsException will be thrown if a UUID conflict is
* detected
+ * @param removedExistingNodes the set into which should be placed all of the existing nodes that were removed as a result of
+ * this clone operation, or null if these nodes need not be collected
* @return the new node, which is the top of the new subgraph
* @throws UuidAlreadyExistsException if {@code removeExisting} is true and and a UUID in the source tree already exists in
* the new workspace
@@ -172,7 +176,8 @@
MapNode newParent,
Name desiredName,
Path.Segment desiredSegment,
- boolean removeExisting ) throws UuidAlreadyExistsException;
+ boolean removeExisting,
+ Set<Location> removedExistingNodes ) throws UuidAlreadyExistsException;
/**
* Find the lowest existing node along the path.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneBranchRequest.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneBranchRequest.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/request/CloneBranchRequest.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -1,5 +1,7 @@
package org.jboss.dna.graph.request;
+import java.util.Collections;
+import java.util.Set;
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.common.util.HashCode;
import org.jboss.dna.graph.GraphI18n;
@@ -33,6 +35,7 @@
private final Name desiredName;
private final Path.Segment desiredSegment;
private final boolean removeExisting;
+ private Set<Location> removedExistingNodes;
private Location actualFromLocation;
private Location actualIntoLocation;
@@ -225,6 +228,24 @@
}
/**
+ * Set the locations of the nodes that were removed by this operation, if {@link #removeExisting()} is true.
+ *
+ * @param existingNodesThatWereRemoved the (immutable) set of existing node locations; may be null
+ */
+ public void setRemovedNodes( Set<Location> existingNodesThatWereRemoved ) {
+ this.removedExistingNodes = existingNodesThatWereRemoved;
+ }
+
+ /**
+ * Get the set of nodes that were removed because of this clone operation.
+ *
+ * @return the immutable set of locations of the nodes that were removed; never null but possibly empty
+ */
+ public Set<Location> getRemovedNodes() {
+ return removedExistingNodes != null ? removedExistingNodes : Collections.<Location>emptySet();
+ }
+
+ /**
* {@inheritDoc}
*
* @see org.jboss.dna.graph.request.ChangeRequest#changes(java.lang.String, org.jboss.dna.graph.property.Path)
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -62,6 +62,7 @@
import org.jboss.dna.graph.request.CloneBranchRequest;
import org.jboss.dna.graph.request.CopyBranchRequest;
import org.jboss.dna.graph.request.InvalidWorkspaceException;
+import org.jboss.dna.graph.request.MoveBranchRequest;
import org.jboss.dna.graph.request.Request;
import org.jboss.dna.graph.session.GraphSession.Authorizer.Action;
import com.google.common.collect.ListMultimap;
@@ -486,7 +487,17 @@
authorizer.checkPermissions(newParentPath, Action.ADD_NODE);
authorizer.checkPermissions(nodeToMove.getParent(), Action.REMOVE);
- store.move(nodeToMove).as(newName).into(newParentPath);
+ // Perform the move operation, but use a batch so that we can read the latest list of children ...
+ Results results = store.batch().move(nodeToMove).as(newName).into(newParentPath).execute();
+ MoveBranchRequest moveRequest = (MoveBranchRequest)results.getRequests().get(0);
+ Location locationAfter = moveRequest.getActualLocationAfter();
+
+ // Find the parent node in the session ...
+ Node<Payload, PropertyPayload> parent = this.findNodeWith(locationAfter.getPath().getParent(), false);
+ if (parent != null && parent.isLoaded()) {
+ // Update the children to make them match the latest snapshot from the store ...
+ parent.synchronizeWithNewlyPersistedNode(locationAfter);
+ }
}
/**
@@ -633,6 +644,12 @@
CloneBranchRequest request = (CloneBranchRequest)results.getRequests().get(0);
Location locationOfCopy = request.getActualLocationAfter();
+ // Remove from the session all of the nodes that were removed as part of this clone ...
+ for (Location removed : request.getRemovedNodes()) {
+ Node<Payload, PropertyPayload> removedNode = findNodeWith(removed.getPath(), false);
+ if (removedNode != null) removedNode.remove(false);
+ }
+
// Find the parent node in the session ...
Node<Payload, PropertyPayload> parent = this.findNodeWith(locationOfCopy.getPath().getParent(), false);
if (parent != null && parent.isLoaded()) {
@@ -2097,13 +2114,26 @@
* is added to a different parent. However, the locations of same-name-siblings under the parent <i>are</i> updated.
*/
protected void remove() {
+ remove(true);
+ }
+
+ /**
+ * Remove this node from it's parent. Note that locations are <i>not</i> updated, since they will be updated if this node
+ * is added to a different parent. However, the locations of same-name-siblings under the parent <i>are</i> updated.
+ *
+ * @param markParentAsChanged true if the parent should be marked as being changed (i.e., when changes are initiated from
+ * within this session), or false otherwise (i.e., when changes are made to reflect the persistent state)
+ */
+ protected void remove( boolean markParentAsChanged ) {
assert !isStale();
assert this.parent != null;
assert this.parent.isLoaded();
assert this.parent.childrenByName != null;
assert this.parent.childrenByName != cache.NO_CHILDREN;
- this.parent.markAsChanged();
- this.markAsChanged();
+ if (markParentAsChanged) {
+ this.parent.markAsChanged();
+ this.markAsChanged();
+ }
Name name = getName();
List<Node<Payload, PropertyPayload>> childrenWithSameName = this.parent.childrenByName.get(name);
this.parent = null;
Modified: trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java
===================================================================
--- trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-graph/src/test/java/org/jboss/dna/graph/connector/test/WritableConnectorTest.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -1001,7 +1001,7 @@
graph.create("/segmentTestUuids/node1", propFactory.create(name("identifier"), "backup copy")).and();
// Copy again to test the behavior now that the UUIDs are already in the default workspace
- // This should remove /newUuids/node1/shouldBeRemoved
+ // This should remove /segmentTestUuids/node1[1]
graph.clone("/node1")
.fromWorkspace(workspaceName)
.as(segment("node1[1]"))
@@ -1011,7 +1011,9 @@
/*
* Focus on testing node structure, since shouldCopyNodeWithChildren tests that properties get copied
*/
- // /newUuids/node1 should have been removed when the new node was added with the same UUID
+ // /segmentTestUuids/node1[1] should have been removed when the new node was added with the same UUID
+ // Now "/segmentTestUuids/node1[1]" (which was "/segmentTestUuids/node1[2]") should have same UUID as the
+ // node with "identifier=backup copy" property
assertThat(graph.getNodeAt("/segmentTestUuids").getChildren(), hasChildren(segment("node1"), segment("node1[2]")));
assertThat(graph.getNodeAt("/segmentTestUuids/node1[1]").getProperty("identifier"), is(nullValue()));
assertThat(graph.getNodeAt("/segmentTestUuids/node1[2]").getProperty("identifier").getFirstValue().toString(),
@@ -1092,7 +1094,7 @@
graph.move("/node2").before("/node2");
assertThat(graph.getChildren().of("/"), hasChildren(segment("node1"), segment("node2"), segment("node3")));
- }
+ }
@Test
public void shouldMoveNodes() {
@@ -1859,7 +1861,7 @@
Stopwatch sw = new Stopwatch();
boolean batch = true;
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
-
+
assertThat(graph.getChildren().of("/"), hasChildren(segment("node1")));
Subgraph subgraph = graph.getSubgraphOfDepth(2).at("/");
assertThat(subgraph, is(notNullValue()));
@@ -1888,7 +1890,7 @@
Stopwatch sw = new Stopwatch();
boolean batch = true;
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
-
+
assertThat(graph.getChildren().of("/"), hasChildren(segment("node1")));
graph.addValue("foo").andValue("bar").to("newProperty").on("node1");
@@ -1912,7 +1914,7 @@
Stopwatch sw = new Stopwatch();
boolean batch = true;
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
-
+
assertThat(graph.getChildren().of("/"), hasChildren(segment("node1")));
graph.removeValue("The quick brown fox jumped over the moon. What? ").andValue("bar").from("property1").on("node1");
@@ -1934,7 +1936,7 @@
Stopwatch sw = new Stopwatch();
boolean batch = true;
createSubgraph(graph, initialPath, depth, numChildrenPerNode, numPropertiesPerNode, batch, sw, System.out, null);
-
+
assertThat(graph.getChildren().of("/"), hasChildren(segment("node1")));
graph.removeValue("The quick brown fox jumped over the moon. What? ").from("noSuchProperty").on("node1");
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrI18n.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -96,6 +96,7 @@
public static I18n unableToSaveBranchBecauseChangesDependOnChangesToNodesOutsideOfBranch;
public static I18n allPropertyValuesMustHaveSameType;
public static I18n cannotRemoveNodeFromClone;
+ public static I18n cannotRemoveNodeFromCloneDueToChangesInSession;
public static I18n cannotRemoveParentNodeOfTarget;
public static I18n invalidPropertyType;
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrWorkspace.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -346,6 +346,12 @@
String path = node.getPath().getString(context.getNamespaceRegistry());
throw new ConstraintViolationException(JcrI18n.cannotRemoveNodeFromClone.text(path, uuid));
}
+ // Check whether the node has any local changes ...
+ if (node.isChanged(true)) {
+ // This session has changes on nodes that will be removed as a result of the clone ...
+ String path = node.getPath().getString(context.getNamespaceRegistry());
+ throw new RepositoryException(JcrI18n.cannotRemoveNodeFromCloneDueToChangesInSession.text(path, uuid));
+ }
}
}
}
Modified: trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties
===================================================================
--- trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-jcr/src/main/resources/org/jboss/dna/jcr/JcrI18n.properties 2009-08-28 15:26:27 UTC (rev 1180)
@@ -86,6 +86,7 @@
unableToSaveBranchBecauseChangesDependOnChangesToNodesOutsideOfBranch = Unable to save "{0}" in workspace "{1}" because it contains changes that depend on changes to nodes outside of this branch
allPropertyValuesMustHaveSameType = All values of property "{0}" on node "{3}" in workspace "{4}" must all be {2} values (values were: {1})
cannotRemoveNodeFromClone = The node at "{0}" with UUID "{1}" exists in the current workspace but cannot be removed because it is a mandatory child node
+cannotRemoveNodeFromCloneDueToChangesInSession = The node at "{0}" with UUID "{1}" already exists in the current workspace and would be removed by the clone, but that node has been changed within this session and therefore cannot be removed
cannotRemoveParentNodeOfTarget = The node at "{0}" with UUID "{1}" is a parent of the target node for this operation "{2}"
invalidPropertyType = Invalid property type: {0}
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -65,6 +65,7 @@
import org.apache.jackrabbit.test.api.SetValueValueFormatExceptionTest;
import org.apache.jackrabbit.test.api.SetValueVersionExceptionTest;
import org.apache.jackrabbit.test.api.ValueFactoryTest;
+import org.apache.jackrabbit.test.api.WorkspaceCloneReferenceableTest;
import org.apache.jackrabbit.test.api.WorkspaceCloneSameNameSibsTest;
import org.apache.jackrabbit.test.api.WorkspaceCloneVersionableTest;
import org.apache.jackrabbit.test.api.WorkspaceCopyBetweenWorkspacesReferenceableTest;
@@ -74,6 +75,7 @@
import org.apache.jackrabbit.test.api.WorkspaceCopyReferenceableTest;
import org.apache.jackrabbit.test.api.WorkspaceCopySameNameSibsTest;
import org.apache.jackrabbit.test.api.WorkspaceCopyVersionableTest;
+import org.apache.jackrabbit.test.api.WorkspaceMoveReferenceableTest;
import org.apache.jackrabbit.test.api.WorkspaceMoveSameNameSibsTest;
import org.apache.jackrabbit.test.api.WorkspaceMoveVersionableTest;
@@ -230,7 +232,7 @@
addTestSuite(NodeCanAddMixinTest.class);
addTestSuite(NodeRemoveMixinTest.class);
- // dna-466 addTestSuite(WorkspaceCloneReferenceableTest.class);
+ addTestSuite(WorkspaceCloneReferenceableTest.class);
addTestSuite(WorkspaceCloneSameNameSibsTest.class);
// addTestSuite(WorkspaceCloneTest.class);
addTestSuite(WorkspaceCloneVersionableTest.class);
@@ -242,7 +244,7 @@
addTestSuite(WorkspaceCopySameNameSibsTest.class);
// addTestSuite(WorkspaceCopyTest.class);
addTestSuite(WorkspaceCopyVersionableTest.class);
- // dna-466 addTestSuite(WorkspaceMoveReferenceableTest.class);
+ addTestSuite(WorkspaceMoveReferenceableTest.class);
addTestSuite(WorkspaceMoveSameNameSibsTest.class);
// addTestSuite(WorkspaceMoveTest.class);
addTestSuite(WorkspaceMoveVersionableTest.class);
Modified: trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/extensions/dna-connector-federation/src/main/java/org/jboss/dna/connector/federation/FederatingRequestProcessor.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -325,8 +325,8 @@
}
// Delete in the cache ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.at(),
- workspace.getCacheProjection().getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.at(), workspace.getCacheProjection()
+ .getWorkspaceName());
executeInCache(cacheRequest, workspace);
}
@@ -380,8 +380,8 @@
}
// Delete from the cache the parent of the new location ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.into(),
- fromWorkspace.getCacheProjection().getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.into(), fromWorkspace.getCacheProjection()
+ .getWorkspaceName());
executeInCache(cacheRequest, fromWorkspace);
}
@@ -433,11 +433,14 @@
} else {
request.setActualLocations(fromProjection.convertToRepository(sourceRequest.getActualLocationBefore()),
intoProjection.convertToRepository(sourceRequest.getActualLocationAfter()));
+ if (sourceRequest.removeExisting()) {
+ request.setRemovedNodes(Collections.unmodifiableSet(intoProjection.convertToRepository(sourceRequest.getRemovedNodes())));
+ }
}
// Delete from the cache the parent of the new location ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.into(),
- fromWorkspace.getCacheProjection().getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.into(), fromWorkspace.getCacheProjection()
+ .getWorkspaceName());
executeInCache(cacheRequest, fromWorkspace);
}
@@ -484,8 +487,8 @@
intoProjection.convertToRepository(sourceRequest.getActualLocationAfter()));
}
// Delete from the cache ...
- DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.from(),
- workspace.getCacheProjection().getWorkspaceName());
+ DeleteBranchRequest cacheRequest = new DeleteBranchRequest(request.from(), workspace.getCacheProjection()
+ .getWorkspaceName());
executeInCache(cacheRequest, workspace);
// Mark the new parent node as being expired ...
cacheRequest = new DeleteBranchRequest(request.into(), workspace.getCacheProjection().getWorkspaceName());
@@ -520,8 +523,8 @@
}
// Update the cache ...
- UpdatePropertiesRequest cacheRequest = new UpdatePropertiesRequest(request.on(),
- workspace.getCacheProjection().getWorkspaceName(),
+ UpdatePropertiesRequest cacheRequest = new UpdatePropertiesRequest(request.on(), workspace.getCacheProjection()
+ .getWorkspaceName(),
request.properties());
executeInCache(cacheRequest, workspace);
}
@@ -598,7 +601,7 @@
this.pathInSource = pathInSource;
}
- protected Location convertToRepository( Location sourceLocation ) {
+ protected final Location convertToRepository( Location sourceLocation ) {
assert sourceLocation != null;
if (sourceLocation.hasPath()) {
Set<Path> paths = projection.getPathsInRepository(sourceLocation.getPath(), pathFactory);
@@ -607,6 +610,15 @@
}
return sourceLocation;
}
+
+ protected Set<Location> convertToRepository( Set<Location> sourceLocations ) {
+ assert sourceLocations != null;
+ Set<Location> results = new HashSet<Location>();
+ for (Location sourceLocation : sourceLocations) {
+ results.add(convertToRepository(sourceLocation));
+ }
+ return results;
+ }
}
protected SingleProjection asSingleProjection( FederatedWorkspace federatedWorkspace,
@@ -1206,9 +1218,9 @@
readable(registry, create.properties()));
} else if (request instanceof UpdatePropertiesRequest) {
UpdatePropertiesRequest update = (UpdatePropertiesRequest)request;
- logger.trace(" updating {0} with properties {1}",
- update.on().getString(registry),
- readable(registry, update.properties().values()));
+ logger.trace(" updating {0} with properties {1}", update.on().getString(registry), readable(registry,
+ update.properties()
+ .values()));
} else {
logger.trace(" " + request.toString());
}
@@ -1227,9 +1239,9 @@
readable(registry, create.properties()));
} else if (request instanceof UpdatePropertiesRequest) {
UpdatePropertiesRequest update = (UpdatePropertiesRequest)request;
- logger.trace(" updating {0} with properties {1}",
- update.on().getString(registry),
- readable(registry, update.properties().values()));
+ logger.trace(" updating {0} with properties {1}", update.on().getString(registry), readable(registry,
+ update.properties()
+ .values()));
} else {
logger.trace(" " + request.toString());
}
Modified: trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -703,6 +703,7 @@
}
request.setActualLocations(copy.getActualLocationBefore(), copy.getActualLocationAfter());
+ request.setRemovedNodes(null);
}
/**
Modified: trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-08-27 14:04:45 UTC (rev 1179)
+++ trunk/extensions/dna-connector-store-jpa/src/main/java/org/jboss/dna/connector/store/jpa/model/basic/BasicRequestProcessor.java 2009-08-28 15:26:27 UTC (rev 1180)
@@ -961,7 +961,7 @@
oos.close();
}
}
-
+
// The new large values were recorded and associated with the properties entity during reserialization.
// However, any values no longer used now need to be removed ...
if (hadLargeValues) {
@@ -1427,6 +1427,7 @@
logger.trace(request.toString());
Location actualFromLocation = null;
Location actualToLocation = null;
+ Set<Location> removedLocations = null;
try {
// Find the workspaces ...
WorkspaceEntity fromWorkspace = getExistingWorkspace(request.fromWorkspace(), request);
@@ -1652,6 +1653,7 @@
}
// Remove from the cache of children locations all entries for deleted nodes ...
cache.removeBranch(intoWorkspaceId, deletedLocations.values());
+ removedLocations = Collections.unmodifiableSet(new HashSet<Location>(deletedLocations.values()));
}
LargeValueEntity.deleteUnused(entities);
}
@@ -1668,6 +1670,7 @@
return;
}
request.setActualLocations(actualFromLocation, actualToLocation);
+ request.setRemovedNodes(removedLocations);
recordChange(request);
}
@@ -1932,7 +1935,7 @@
}
assert beforeEntity != null;
-
+
Name childName = oldPath.getLastSegment().getName();
String childLocalName = fromEntity.getChildName();
NamespaceEntity ns = fromEntity.getChildNamespace();
@@ -2084,8 +2087,8 @@
} else {
ActualLocation actualBeforeLocation = getActualLocation(workspace, beforeLocation);
- ActualLocation actualIntoLocation = getActualLocation(workspace,
- Location.create(beforeLocation.getPath().getParent()));
+ ActualLocation actualIntoLocation = getActualLocation(workspace, Location.create(beforeLocation.getPath()
+ .getParent()));
actualNewLocation = moveNodeBefore(workspace, actualLocation, actualIntoLocation, actualBeforeLocation);
}
@@ -2429,7 +2432,7 @@
props.setData(baos.toByteArray());
props.setPropertyCount(numProperties);
-
+
// Record the changes to the references ...
if (refs != null && refs.hasWritten()) {
for (Reference reference : refs.getWritten()) {
@@ -2555,7 +2558,7 @@
}
}
Path fullPath = pathFactory.createAbsolutePath(segments);
- Location newLocation = original.with(fullPath);
+ Location newLocation = original.with(fullPath);
cache.addNewNode(workspaceId, newLocation);
return new ActualLocation(newLocation, nodeUuidString, originalEntity);
}
@@ -2578,13 +2581,13 @@
if (cachedParent != null) {
// We know the UUID of the parent, so we can find the child a little faster ...
ChildEntity child = findByPathSegment(workspaceId, cachedParent.getUuid().toString(), path.getLastSegment());
-
+
// If there is no matching child, throw an exception
if (child == null) {
// Could not find the node given the supplied path, so find the lowest path that does exist ...
throw new PathNotFoundException(original, cachedParent.getPath(), JpaConnectorI18n.nodeDoesNotExist.text(path));
}
-
+
uuidString = child.getId().getChildUuidString();
Location newLocation = original.with(UUID.fromString(uuidString));
cache.addNewNode(workspaceId, newLocation);
@@ -2614,7 +2617,8 @@
return new ActualLocation(newLocation, uuidString, child);
}
- protected ChildEntity findNode( long workspaceId, String uuidString) {
+ protected ChildEntity findNode( long workspaceId,
+ String uuidString ) {
Query query = entities.createNamedQuery("ChildEntity.findByChildUuid");
query.setParameter("workspaceId", workspaceId);
query.setParameter("childUuidString", uuidString);
@@ -2625,7 +2629,7 @@
return null;
}
}
-
+
/**
* Find the node with the supplied path segment that is a child of the supplied parent.
*
14 years, 8 months
DNA SVN: r1179 - in trunk: dna-jcr/src/main/java/org/jboss/dna/jcr and 1 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-08-27 10:04:45 -0400 (Thu, 27 Aug 2009)
New Revision: 1179
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java
Log:
DNA-478 Refresh does not properly reflect changes made in other sessions
Several TCK unit tests were reporting this issue as an error. The problem stemmed from an improperly-coded method that was attempting to refresh the children of a node, where one (or more) of the children had been changed/created locally in the session. The method was in fact (partially) losing those local changes and was actually corrupting the cached state. This method has been fixed and now correctly updates those children. The TCK unit tests were uncommented, since they now pass.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java 2009-08-26 21:16:25 UTC (rev 1178)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/session/GraphSession.java 2009-08-27 14:04:45 UTC (rev 1179)
@@ -1515,29 +1515,53 @@
assert childrenByName != null;
org.jboss.dna.graph.Node persistentNode = persistentInfoForRefreshedNodes.getNode(location);
assert !persistentNode.getChildren().isEmpty();
- // Find the map of old Node objects keyed by their identifier ...
- Map<NodeId, Node<Payload, PropertyPayload>> oldChildren = new HashMap<NodeId, Node<Payload, PropertyPayload>>();
- for (Node<Payload, PropertyPayload> oldChild : childrenByName.values()) {
- oldChildren.put(oldChild.getNodeId(), oldChild);
+
+ // We need to keep the children that have been modified (or are ancestors of modified children),
+ // so build a list of the children that SHOULD NOT be replaced with the persistent info ...
+ Map<Location, Node<Payload, PropertyPayload>> childrenToKeep = new HashMap<Location, Node<Payload, PropertyPayload>>();
+ for (Node<Payload, PropertyPayload> existing : childrenByName.values()) {
+ if (existing.isChanged(true)) {
+ childrenToKeep.put(existing.getLocation(), existing);
+ } else {
+ // Otherwise, remove the child from the cache since we won't be needing it anymore ...
+ cache.nodes.remove(existing.getNodeId());
+ assert !cache.changeDependencies.containsKey(existing.getNodeId());
+ existing.parent = null;
+ }
}
+
+ // Now, clear the children ...
childrenByName.clear();
+
+ // And add the persistent children ...
for (Location location : persistentNode.getChildren()) {
Name childName = location.getPath().getLastSegment().getName();
- NodeId nodeId = cache.idFactory.create();
- Node<Payload, PropertyPayload> child = oldChildren.remove(nodeId);
- if (child == null) {
- child = cache.createNode(this, nodeId, location);
- cache.nodes.put(child.getNodeId(), child);
- assert child.getName().equals(childName);
+ List<Node<Payload, PropertyPayload>> currentChildren = childrenByName.get(childName);
+ // Find if there was an existing child that is supposed to stay ...
+ Node<Payload, PropertyPayload> existingChild = childrenToKeep.get(location);
+ if (existingChild != null) {
+ // The existing child is supposed to stay, since it has changes ...
+ currentChildren.add(existingChild);
+ if (currentChildren.size() != existingChild.getPath().getLastSegment().getIndex()) {
+ // Make sure the SNS index is correct ...
+ Path.Segment segment = cache.pathFactory.createSegment(childName, currentChildren.size());
+ existingChild.updateLocation(segment);
+ // TODO: Can the location be different? If so, doesn't that mean that the change requests
+ // have to be updated???
+ }
+ } else {
+ // The existing child (if there was one) is to be refreshed ...
+ NodeId nodeId = cache.idFactory.create();
+ Node<Payload, PropertyPayload> replacementChild = cache.createNode(this, nodeId, location);
+ cache.nodes.put(replacementChild.getNodeId(), replacementChild);
+ assert replacementChild.getName().equals(childName);
+ assert replacementChild.parent == this;
+ // Add it to the parent node ...
+ currentChildren.add(replacementChild);
+ // Create a segment with the SNS ...
+ Path.Segment segment = cache.pathFactory.createSegment(childName, currentChildren.size());
+ replacementChild.updateLocation(segment);
}
- assert child.parent == this;
- List<Node<Payload, PropertyPayload>> currentChildren = childrenByName.get(childName);
- currentChildren.add(child);
- // Create a segment with the SNS ...
- Path.Segment segment = cache.pathFactory.createSegment(childName, currentChildren.size());
- child.updateLocation(segment);
- // TODO: Can the location be different? If so, doesn't that mean that the change requests
- // have to be updated???
}
return;
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-08-26 21:16:25 UTC (rev 1178)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/AbstractJcrNode.java 2009-08-27 14:04:45 UTC (rev 1179)
@@ -1588,8 +1588,8 @@
if (destChildRelPath != null) {
Path destPath = pathFactory.create(destChildRelPath);
if (destPath.isAbsolute() || destPath.size() != 1) {
- throw new ItemNotFoundException(
- JcrI18n.pathNotFound.text(destPath.getString(cache.context().getNamespaceRegistry()),
+ throw new ItemNotFoundException(JcrI18n.pathNotFound.text(destPath.getString(cache.context()
+ .getNamespaceRegistry()),
cache.session().workspace().getName()));
}
@@ -1670,7 +1670,7 @@
* @see javax.jcr.Item#refresh(boolean)
*/
public void refresh( boolean keepChanges ) throws RepositoryException {
- this.cache.refresh(this.nodeId, keepChanges);
+ this.cache.refresh(this.nodeId, location.getPath(), keepChanges);
}
/**
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-08-26 21:16:25 UTC (rev 1178)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-08-27 14:04:45 UTC (rev 1179)
@@ -281,18 +281,22 @@
* </p>
*
* @param nodeId the identifier of the node that is to be saved; may not be null
+ * @param absolutePath the absolute path to the node; may not be null
* @param keepChanges indicates whether changed nodes should be kept or refreshed from the repository.
* @throws InvalidItemStateException if the node being refreshed no longer exists
* @throws RepositoryException if any error resulting while saving the changes to the repository
*/
public void refresh( NodeId nodeId,
+ Path absolutePath,
boolean keepChanges ) throws InvalidItemStateException, RepositoryException {
assert nodeId != null;
try {
- Node<JcrNodePayload, JcrPropertyPayload> node = graphSession.findNodeWith(nodeId);
+ Node<JcrNodePayload, JcrPropertyPayload> node = graphSession.findNodeWith(nodeId, absolutePath);
graphSession.refresh(node, keepChanges);
} catch (InvalidStateException e) {
throw new InvalidItemStateException(e.getLocalizedMessage());
+ } catch (org.jboss.dna.graph.property.PathNotFoundException e) {
+ throw new InvalidItemStateException(e.getLocalizedMessage());
} catch (RepositorySourceException e) {
throw new RepositoryException(e.getLocalizedMessage());
}
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java 2009-08-26 21:16:25 UTC (rev 1178)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrTckTest.java 2009-08-27 14:04:45 UTC (rev 1179)
@@ -37,11 +37,13 @@
import org.apache.jackrabbit.test.api.NodeItemIsNewTest;
import org.apache.jackrabbit.test.api.NodeOrderableChildNodesTest;
import org.apache.jackrabbit.test.api.NodeRemoveMixinTest;
+import org.apache.jackrabbit.test.api.NodeTest;
import org.apache.jackrabbit.test.api.PropertyItemIsModifiedTest;
import org.apache.jackrabbit.test.api.PropertyItemIsNewTest;
import org.apache.jackrabbit.test.api.PropertyTest;
import org.apache.jackrabbit.test.api.RepositoryLoginTest;
import org.apache.jackrabbit.test.api.SerializationTest;
+import org.apache.jackrabbit.test.api.SessionTest;
import org.apache.jackrabbit.test.api.SetPropertyAssumeTypeTest;
import org.apache.jackrabbit.test.api.SetPropertyBooleanTest;
import org.apache.jackrabbit.test.api.SetPropertyCalendarTest;
@@ -190,9 +192,9 @@
addTestSuite(AddNodeTest.class);
addTestSuite(NamespaceRegistryTest.class);
// addTestSuite(ReferencesTest.class);
- // dna-466 addTestSuite(SessionTest.class);
+ addTestSuite(SessionTest.class);
// addTestSuite(SessionUUIDTest.class);
- // dna-466 addTestSuite(NodeTest.class);
+ addTestSuite(NodeTest.class);
// addTestSuite(NodeUUIDTest.class);
addTestSuite(NodeOrderableChildNodesTest.class);
addTestSuite(PropertyTest.class);
14 years, 8 months
DNA SVN: r1178 - trunk/dna-jcr/src/test/java/org/jboss/dna/jcr.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-08-26 17:16:25 -0400 (Wed, 26 Aug 2009)
New Revision: 1178
Modified:
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
Log:
Merge branch 'quick_patch'
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java 2009-08-26 20:57:41 UTC (rev 1177)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java 2009-08-26 21:16:25 UTC (rev 1178)
@@ -203,6 +203,7 @@
repository.login();
}
+ @SuppressWarnings( "cast" )
@Test
public void shouldAllowLoginWithNoCredentialsInPrivilegedBlock() throws Exception {
LoginContext login = new LoginContext("dna-jcr", new UserPasswordCallbackHandler("superuser", "superuser".toCharArray()));
@@ -210,7 +211,7 @@
Subject subject = login.getSubject();
- Session session = Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<Session>() {
+ Session session = (Session)Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<Session>() {
@SuppressWarnings( "synthetic-access" )
public Session run() throws Exception {
14 years, 8 months
DNA SVN: r1177 - in trunk/extensions/dna-connector-filesystem/src: test/java/org/jboss/dna/connector/filesystem and 1 other directory.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-08-26 16:57:41 -0400 (Wed, 26 Aug 2009)
New Revision: 1177
Modified:
trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
trunk/extensions/dna-connector-filesystem/src/test/java/org/jboss/dna/connector/filesystem/FileSystemConnectorWritableTest.java
Log:
Merge branch 'quick_patch'
Modified: trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java
===================================================================
--- trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-08-26 20:51:58 UTC (rev 1176)
+++ trunk/extensions/dna-connector-filesystem/src/main/java/org/jboss/dna/connector/filesystem/FileSystemRequestProcessor.java 2009-08-26 20:57:41 UTC (rev 1177)
@@ -458,7 +458,6 @@
} finally {
try {
if (checkForContents != null) checkForContents.close();
- checkForContents.close();
} catch (Exception ignore) {
}
}
Modified: trunk/extensions/dna-connector-filesystem/src/test/java/org/jboss/dna/connector/filesystem/FileSystemConnectorWritableTest.java
===================================================================
--- trunk/extensions/dna-connector-filesystem/src/test/java/org/jboss/dna/connector/filesystem/FileSystemConnectorWritableTest.java 2009-08-26 20:51:58 UTC (rev 1176)
+++ trunk/extensions/dna-connector-filesystem/src/test/java/org/jboss/dna/connector/filesystem/FileSystemConnectorWritableTest.java 2009-08-26 20:57:41 UTC (rev 1177)
@@ -101,8 +101,11 @@
@Test
public void shouldBeAbleToCreateFileWithContent() {
graph.create("/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFile");
assertContents(newFile, TEST_CONTENT);
@@ -111,11 +114,17 @@
@Test
public void shouldRespectConflictBehaviorOnCreate() {
graph.create("/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
- graph.create("/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- "Should not overwrite".getBytes()).ifAbsent().and();
+ graph.create("/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, "Should not overwrite".getBytes())
+ .ifAbsent()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFile");
assertContents(newFile, TEST_CONTENT);
@@ -147,10 +156,13 @@
assertThat(newFolder.exists(), is(true));
assertThat(newFolder.isDirectory(), is(true));
System.out.println("Created new folder at: " + newFolder.getCanonicalPath());
-
+
graph.create("/testFolder/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFolder/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFolder/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFolder/testFile");
assertContents(newFile, TEST_CONTENT);
@@ -170,8 +182,11 @@
@Test
public void shouldBeAbleToCopyFile() {
graph.create("/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFile");
assertContents(newFile, TEST_CONTENT);
@@ -185,8 +200,11 @@
public void shouldBeAbleToCopyFolder() {
graph.create("/testFolder").orReplace().and();
graph.create("/testFolder/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFolder/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFolder/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFolder/testFile");
assertContents(newFile, TEST_CONTENT);
@@ -203,8 +221,11 @@
@Test
public void shouldBeAbleToMoveFile() {
graph.create("/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFile");
assertContents(newFile, TEST_CONTENT);
@@ -222,8 +243,11 @@
public void shouldBeAbleToMoveFolder() {
graph.create("/testFolder").orReplace().and();
graph.create("/testFolder/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFolder/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFolder/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFolder/testFile");
assertContents(newFile, TEST_CONTENT);
@@ -245,8 +269,11 @@
public void shouldBeAbleToDeleteFolderWithContents() {
graph.create("/testFolder").orReplace().and();
graph.create("/testFolder/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFolder/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFolder/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFolder = new File(testWorkspaceRoot, "testFolder");
assertTrue(newFolder.exists());
@@ -264,8 +291,11 @@
public void shouldBeAbleToDeleteFile() {
graph.create("/testFolder").orReplace().and();
graph.create("/testFolder/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFolder/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFolder/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFolder = new File(testWorkspaceRoot, "testFolder");
assertTrue(newFolder.exists());
@@ -289,8 +319,11 @@
graph.useWorkspace("otherWorkspace");
graph.create("/testFolder").orReplace().and();
graph.create("/testFolder/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFolder/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFolder/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(otherWorkspaceRoot, "testFolder/testFile");
assertContents(newFile, TEST_CONTENT);
@@ -313,8 +346,11 @@
public void shouldBeAbleToCloneFile() {
graph.useWorkspace("otherWorkspace");
graph.create("/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(otherWorkspaceRoot, "testFile");
assertContents(newFile, TEST_CONTENT);
@@ -345,11 +381,17 @@
public void shouldNotBeAbleToReorderFile() {
graph.create("/testFolder").orReplace().and();
graph.create("/testFolder/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFolder/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFolder/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
graph.create("/testFolder/testFile2").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFolder/testFile2/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFolder/testFile2/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFolder = new File(testWorkspaceRoot, "testFolder");
assertTrue(newFolder.exists());
@@ -367,8 +409,11 @@
public void shouldBeAbleToRenameFolder() {
graph.create("/testFolder").orReplace().and();
graph.create("/testFolder/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFolder/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFolder/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFolder/testFile");
assertContents(newFile, TEST_CONTENT);
@@ -387,8 +432,11 @@
@Test
public void shouldBeAbleToRenameFile() {
graph.create("/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFile");
assertContents(newFile, TEST_CONTENT);
@@ -407,8 +455,11 @@
graph.useWorkspace("newWorkspace");
graph.create("/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(newWorkspaceRoot, "testFile");
assertContents(newFile, TEST_CONTENT);
@@ -417,8 +468,11 @@
@Test
public void shouldBeAbleToCloneWorkspace() {
graph.create("/testFile").with(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE).orReplace().and();
- graph.create("/testFile/jcr:content").with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE).and(JcrLexicon.DATA,
- TEST_CONTENT.getBytes()).orReplace().and();
+ graph.create("/testFile/jcr:content")
+ .with(JcrLexicon.PRIMARY_TYPE, DnaLexicon.RESOURCE)
+ .and(JcrLexicon.DATA, TEST_CONTENT.getBytes())
+ .orReplace()
+ .and();
File newFile = new File(testWorkspaceRoot, "testFile");
assertContents(newFile, TEST_CONTENT);
@@ -474,9 +528,13 @@
fail(ioe.getMessage());
return;
} finally {
- try {
- fis.close();
- } catch (Exception ignore) {
+ if (fis != null) {
+ try {
+ fis.close();
+ } catch (Exception ignore) {
+ } finally {
+ fis = null;
+ }
}
}
}
14 years, 8 months
DNA SVN: r1176 - trunk/dna-jcr/src/test/java/org/jboss/dna/jcr.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-08-26 16:51:58 -0400 (Wed, 26 Aug 2009)
New Revision: 1176
Modified:
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
Log:
Removed compilation warning due to unnecessary cast
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java 2009-08-26 20:43:45 UTC (rev 1175)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrRepositoryTest.java 2009-08-26 20:51:58 UTC (rev 1176)
@@ -210,7 +210,7 @@
Subject subject = login.getSubject();
- Session session = (Session)Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<Session>() {
+ Session session = Subject.doAsPrivileged(subject, new PrivilegedExceptionAction<Session>() {
@SuppressWarnings( "synthetic-access" )
public Session run() throws Exception {
14 years, 8 months
DNA SVN: r1175 - in trunk: dna-graph/src/main/java/org/jboss/dna/graph/property/basic and 6 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-08-26 16:43:45 -0400 (Wed, 26 Aug 2009)
New Revision: 1175
Added:
trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/Path.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/AbstractPath.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/RootPath.java
trunk/dna-integration-tests/pom.xml
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java
trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrConfigurationTest.java
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/SVNRepositoryUtil.java
trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNRepositoryConnectorCreateWorspaceTest.java
Log:
DNA-505 Svn Repository Source with NPE and other issues while opening connection through Jcr
DNA-240 code test case for SVNRepositoryConnection used for connection
One of the NPE issues (DNA-505) was more easily fixed by returning an empty collection; the other was fixed as prescribed in the patch (though there was another situation that required a similar change). A test case was added to the 'dna-connector-svn' project to test using the DNA SVN repository, and this made apparent several other issues. First, the children for a directory were being computed incorrectly; all of the child directories were fine, but the locations of the nt:file nodes were being skipped and instead the path to the nt:file's jcr:content child node were being returned. Second, much of the JCR implementation relies upon ReadNodeRequest instead of the ReadAllPropertiesRequest and ReadAllChildrenRequest. Although the default implementation for ReadNodeRequest uses the other two and is technically correct, it can be quite inefficient, and this was definitely true for the SVN connector. Therefore, the request processor code was refactored to have a single me!
thod compute the children and/or the properties for a node. This not only dramatically reduced the class size, but it dramatically reduced the amount of duplicated code, and it appears to have slightly improved performance (though I think the SVNKit is still the bottleneck).
Finally, a new integration test was added to the 'dna-integration-test' project that very minimally tests using JCR on top of the SVN connector. This may need to be rounded out in the future, but ideally we wouldn't be hitting a remote SVN repository (simply because of the latency issue).
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/Path.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/Path.java 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/Path.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -398,6 +398,25 @@
public Segment getLastSegment();
/**
+ * Determine if the path's {@link #getLastSegment()} has the supplied name and no {@link Segment#getIndex() SNS index}.
+ *
+ * @param nameOfLastSegment the name
+ * @return return true if the supplied name is the name in the path's last segment (and there is no SNS index), or false
+ * otherwise
+ */
+ public boolean endsWith( Name nameOfLastSegment );
+
+ /**
+ * Determine if the path's {@link #getLastSegment()} has the supplied name and {@link Segment#getIndex() SNS index}.
+ *
+ * @param nameOfLastSegment the name
+ * @param snsIndex the SNS index
+ * @return return true if the path's last segment has the supplied name and SNS, or false otherwise
+ */
+ public boolean endsWith( Name nameOfLastSegment,
+ int snsIndex );
+
+ /**
* Get the segment at the supplied index.
*
* @param index the index
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/AbstractPath.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/AbstractPath.java 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/AbstractPath.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -35,6 +35,7 @@
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.property.InvalidPathException;
+import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NamespaceRegistry;
import org.jboss.dna.graph.property.Path;
@@ -187,6 +188,27 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.property.Path#endsWith(org.jboss.dna.graph.property.Name)
+ */
+ public boolean endsWith( Name nameOfLastSegment ) {
+ Segment segment = getLastSegment();
+ return segment != null && segment.getName().equals(nameOfLastSegment) && !segment.hasIndex();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.property.Path#endsWith(org.jboss.dna.graph.property.Name, int)
+ */
+ public boolean endsWith( Name nameOfLastSegment,
+ int snsIndex ) {
+ Segment segment = getLastSegment();
+ return segment != null && segment.getName().equals(nameOfLastSegment) && segment.getIndex() == snsIndex;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.property.Path#getParent()
*/
public Path getParent() {
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/RootPath.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/RootPath.java 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/property/basic/RootPath.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -32,6 +32,7 @@
import org.jboss.dna.common.util.CheckArg;
import org.jboss.dna.graph.GraphI18n;
import org.jboss.dna.graph.property.InvalidPathException;
+import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.NamespaceRegistry;
import org.jboss.dna.graph.property.Path;
@@ -114,6 +115,27 @@
/**
* {@inheritDoc}
*
+ * @see org.jboss.dna.graph.property.basic.AbstractPath#endsWith(org.jboss.dna.graph.property.Name)
+ */
+ @Override
+ public boolean endsWith( Name nameOfLastSegment ) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.property.basic.AbstractPath#endsWith(org.jboss.dna.graph.property.Name, int)
+ */
+ @Override
+ public boolean endsWith( Name nameOfLastSegment,
+ int snsIndex ) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @see org.jboss.dna.graph.property.Path#getNormalizedPath()
*/
@Override
Modified: trunk/dna-integration-tests/pom.xml
===================================================================
--- trunk/dna-integration-tests/pom.xml 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/dna-integration-tests/pom.xml 2009-08-26 20:43:45 UTC (rev 1175)
@@ -81,6 +81,12 @@
<version>${pom.version}</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
+ <artifactId>dna-connector-svn</artifactId>
+ <version>${pom.version}</version>
+ <scope>test</scope>
+ </dependency>
<!--
JPA Connector Dependencies
Added: 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 (rev 0)
+++ trunk/dna-integration-tests/src/test/java/org/jboss/dna/test/integration/SvnAndJcrIntegrationTest.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -0,0 +1,122 @@
+/*
+ * 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 {
+ NodeIterator nodeIterator = this.session.getRootNode().getNodes();
+
+ while (nodeIterator.hasNext()) {
+ System.out.println(nodeIterator.nextNode().getPath());
+ }
+ 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/SvnAndJcrIntegrationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/JcrRepository.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -132,9 +132,14 @@
* Also, any use of the '@' character in source and workspace names must be escaped with a preceding backslash.
* </p>
*/
- SYSTEM_SOURCE_NAME;
+ SYSTEM_SOURCE_NAME,
/**
+ * The depth of the subgraphs that should be loaded the connectors. The default value is 1.
+ */
+ READ_DEPTH;
+
+ /**
* Determine the option given the option name. This does more than {@link Option#valueOf(String)}, since this method first
* tries to match the supplied string to the option's {@link Option#name() name}, then the uppercase version of the
* supplied string to the option's name, and finally if the supplied string is a camel-case version of the name (e.g.,
@@ -176,6 +181,11 @@
* The default value for the {@link Option#JAAS_LOGIN_CONFIG_NAME} option is {@value} .
*/
public static final String JAAS_LOGIN_CONFIG_NAME = "dna-jcr";
+
+ /**
+ * The default value for the {@link Option#READ_DEPTH} option is {@value} .
+ */
+ public static final String READ_DEPTH = "1";
}
/**
@@ -188,6 +198,7 @@
EnumMap<Option, String> defaults = new EnumMap<Option, String>(Option.class);
defaults.put(Option.PROJECT_NODE_TYPES, DefaultOption.PROJECT_NODE_TYPES);
defaults.put(Option.JAAS_LOGIN_CONFIG_NAME, DefaultOption.JAAS_LOGIN_CONFIG_NAME);
+ defaults.put(Option.READ_DEPTH, DefaultOption.READ_DEPTH);
DEFAULT_OPTIONS = Collections.<Option, String>unmodifiableMap(defaults);
}
Modified: trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java
===================================================================
--- trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/dna-jcr/src/main/java/org/jboss/dna/jcr/SessionCache.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -76,6 +76,7 @@
import org.jboss.dna.graph.session.GraphSession.NodeId;
import org.jboss.dna.graph.session.GraphSession.PropertyInfo;
import org.jboss.dna.graph.session.GraphSession.Status;
+import org.jboss.dna.jcr.JcrRepository.Option;
/**
* The class that manages the session's information that has been locally-cached after reading from the underlying {@link Graph
@@ -172,6 +173,12 @@
// Create the graph session, customized for JCR ...
this.graphSession = new GraphSession<JcrNodePayload, JcrPropertyPayload>(this.store, this.workspaceName,
new JcrNodeOperations(), new JcrAuthorizer());
+ // Set the read-depth if we can...
+ try {
+ int depth = Integer.parseInt(session.repository().getOptions().get(Option.READ_DEPTH));
+ if (depth > 0) this.graphSession.setDepthForLoadingNodes(depth);
+ } catch (RuntimeException e) {
+ }
}
final GraphSession<JcrNodePayload, JcrPropertyPayload> graphSession() {
@@ -937,8 +944,7 @@
true,
skipProtected);
if (definition == null) {
- throw new ConstraintViolationException(
- JcrI18n.noDefinition.text("property",
+ throw new ConstraintViolationException(JcrI18n.noDefinition.text("property",
readable(name),
readable(node.getPath()),
readable(payload.getPrimaryTypeName()),
@@ -1114,8 +1120,7 @@
newValues,
skipProtected);
if (definition == null) {
- throw new ConstraintViolationException(
- JcrI18n.noDefinition.text("property",
+ throw new ConstraintViolationException(JcrI18n.noDefinition.text("property",
readable(name),
readable(node.getPath()),
readable(payload.getPrimaryTypeName()),
@@ -1249,8 +1254,8 @@
// The node definition changed, so try to set the property ...
NodeEditor newChildEditor = getEditorFor(existingChild);
try {
- JcrValue value = new JcrValue(factories(), SessionCache.this, PropertyType.STRING,
- defn.getId().getString());
+ JcrValue value = new JcrValue(factories(), SessionCache.this, PropertyType.STRING, defn.getId()
+ .getString());
newChildEditor.setProperty(DnaIntLexicon.NODE_DEFINITON, value);
} catch (ConstraintViolationException e) {
// We can't set this property on the node (according to the node definition).
Modified: trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrConfigurationTest.java
===================================================================
--- trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrConfigurationTest.java 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/dna-jcr/src/test/java/org/jboss/dna/jcr/JcrConfigurationTest.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -48,6 +48,7 @@
import org.jboss.dna.graph.connector.inmemory.InMemoryRepositorySource;
import org.jboss.dna.graph.mimetype.ExtensionBasedMimeTypeDetector;
import org.jboss.dna.graph.property.Path;
+import org.jboss.dna.jcr.JcrRepository.DefaultOption;
import org.jboss.dna.jcr.JcrRepository.Option;
import org.jboss.dna.repository.DnaConfiguration;
import org.jboss.dna.repository.DnaLexicon;
@@ -246,7 +247,8 @@
Map<Option, String> options = new HashMap<Option, String>();
options.put(Option.JAAS_LOGIN_CONFIG_NAME, "test");
- options.put(Option.PROJECT_NODE_TYPES, "false");
+ options.put(Option.PROJECT_NODE_TYPES, DefaultOption.PROJECT_NODE_TYPES);
+ options.put(Option.READ_DEPTH, DefaultOption.READ_DEPTH);
assertThat(repository.getOptions(), is(options));
}
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-08-26 18:10:37 UTC (rev 1174)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryRequestProcessor.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -29,6 +29,8 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Set;
import org.jboss.dna.common.i18n.I18n;
import org.jboss.dna.common.util.Logger;
@@ -63,6 +65,7 @@
import org.jboss.dna.graph.request.MoveBranchRequest;
import org.jboss.dna.graph.request.ReadAllChildrenRequest;
import org.jboss.dna.graph.request.ReadAllPropertiesRequest;
+import org.jboss.dna.graph.request.ReadNodeRequest;
import org.jboss.dna.graph.request.RenameNodeRequest;
import org.jboss.dna.graph.request.Request;
import org.jboss.dna.graph.request.UpdatePropertiesRequest;
@@ -128,188 +131,176 @@
this.accessData = accessData;
}
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllChildrenRequest)
- */
- @Override
- public void process( ReadAllChildrenRequest request ) {
- logger.trace(request.toString());
+ protected boolean readNode( String workspaceName,
+ Location myLocation,
+ List<Property> properties,
+ List<Location> children,
+ Request request ) {
// Get the SVNRepository object that represents the workspace ...
- SVNRepository workspaceRoot = getWorkspaceDirectory(request.inWorkspace());
+ SVNRepository workspaceRoot = getWorkspaceDirectory(workspaceName);
if (workspaceRoot == null) {
- request.setError(new InvalidWorkspaceException(
- SVNRepositoryConnectorI18n.workspaceDoesNotExist.text(request.inWorkspace())));
- return;
+ request.setError(new InvalidWorkspaceException(SVNRepositoryConnectorI18n.workspaceDoesNotExist.text(workspaceName)));
+ return false;
}
- Location myLocation = request.of();
Path requestedPath = getPathFor(myLocation, request);
- // svn connector does not support same name sibling
- checkThePath(requestedPath, request);
- // requested path is the root
+ checkThePath(requestedPath, request); // same-name-sibling indexes are not supported
+
if (requestedPath.isRoot()) {
// workspace root must be a directory
- final Collection<SVNDirEntry> entries = SVNRepositoryUtil.getDir(workspaceRoot, "");
- for (SVNDirEntry entry : entries) {
- // Decide how to represent the children ...
- if (entry.getKind() == SVNNodeKind.DIR) {
- // Create a Location for each file and directory contained by the parent directory ...
+ if (children != null) {
+ final Collection<SVNDirEntry> entries = SVNRepositoryUtil.getDir(workspaceRoot, "");
+ for (SVNDirEntry entry : entries) {
+ // All of the children of a directory will be another directory or a file, but never a "jcr:content" node ...
String localName = entry.getName();
Name childName = nameFactory().create(defaultNamespaceUri, localName);
Path childPath = pathFactory().create(requestedPath, childName);
- request.addChild(Location.create(childPath));
- } else if (entry.getKind() == SVNNodeKind.FILE) {
- // The parent is a file, and the path may refer to the node that is either the "nt:file" parent
- // node, or the child "jcr:content" node...
- String localName = entry.getName();
- Path contentPath = pathFactory().create(BACK_SLASH + localName);
- if (!contentPath.getLastSegment().getName().equals(JcrLexicon.CONTENT)) {
- Location location = Location.create(pathFactory().create(contentPath, JcrLexicon.CONTENT));
- request.addChild(location);
- }
+ children.add(Location.create(childPath));
}
}
+ // There are no properties on the root ...
} else {
try {
- SVNNodeKind kind = getNodeKind(workspaceRoot,
- requestedPath,
- accessData.getRepositoryRootUrl(),
- request.inWorkspace());
+ // Generate the properties for this File object ...
+ PropertyFactory factory = getExecutionContext().getPropertyFactory();
+ DateTimeFactory dateFactory = getExecutionContext().getValueFactories().getDateFactory();
+
+ // Figure out the kind of node this represents ...
+ SVNNodeKind kind = getNodeKind(workspaceRoot, requestedPath, accessData.getRepositoryRootUrl(), workspaceName);
if (kind == SVNNodeKind.DIR) {
String directoryPath = getPathAsString(requestedPath);
- // Decide how to represent the children ...
- if (!accessData.getRepositoryRootUrl().equals(request.inWorkspace())) {
+ if (!accessData.getRepositoryRootUrl().equals(workspaceName)) {
directoryPath = directoryPath.substring(1);
}
- Collection<SVNDirEntry> dirEntries = SVNRepositoryUtil.getDir(workspaceRoot, directoryPath);
- for (SVNDirEntry entry : dirEntries) {
+ if (children != null) {
// Decide how to represent the children ...
- if (entry.getKind() == SVNNodeKind.DIR) {
- // Create a Location for each file and directory contained by the parent directory ...
+ Collection<SVNDirEntry> dirEntries = SVNRepositoryUtil.getDir(workspaceRoot, directoryPath);
+ for (SVNDirEntry entry : dirEntries) {
+ // All of the children of a directory will be another directory or a file,
+ // but never a "jcr:content" node ...
String localName = entry.getName();
Name childName = nameFactory().create(defaultNamespaceUri, localName);
Path childPath = pathFactory().create(requestedPath, childName);
- request.addChild(Location.create(childPath));
- } else if (entry.getKind() == SVNNodeKind.FILE) {
- // The parent is a file, and the path may refer to the node that is either the "nt:file" parent
- // node, or the child "jcr:content" node...
- String localName = entry.getName();
- Path contentPath = pathFactory().create(getPathAsString(requestedPath) + BACK_SLASH + localName);
- Location content = Location.create(pathFactory().create(contentPath, JcrLexicon.CONTENT));
- request.addChild(content);
+ children.add(Location.create(childPath));
}
}
+ if (properties != null) {
+ // Load the properties for this directory ......
+ properties.add(factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FOLDER));
+ SVNDirEntry entry = getEntryInfo(workspaceRoot, directoryPath);
+ if (entry != null) {
+ properties.add(factory.create(JcrLexicon.LAST_MODIFIED, dateFactory.create(entry.getDate())));
+ }
+ }
} else {
- if (!requestedPath.getLastSegment().getName().equals(JcrLexicon.CONTENT)) {
- // Use leading '/' on the requested path
- // repository root URL is exactly the same as the workspace
- // Get the parent path
+ // It's not a directory, so must be a file; the only child of an nt:file is the "jcr:content" node
+ // ...
+ if (requestedPath.endsWith(JcrLexicon.CONTENT)) {
+ // There are never any children of these nodes, just properties ...
+ if (properties != null) {
+ String contentPath = getPathAsString(requestedPath.getParent());
+ if (!accessData.getRepositoryRootUrl().equals(workspaceName)) {
+ contentPath = contentPath.substring(1);
+ }
+ SVNDirEntry entry = getEntryInfo(workspaceRoot, contentPath);
+ if (entry != null) {
+ // The request is to get properties of the "jcr:content" child node ...
+ properties.add(factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.RESOURCE));
+ properties.add(factory.create(JcrLexicon.LAST_MODIFIED, dateFactory.create(entry.getDate())));
+ }
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ SVNProperties fileProperties = new SVNProperties();
+ getData(contentPath, fileProperties, os);
+ String mimeType = fileProperties.getStringValue(SVNProperty.MIME_TYPE);
+ if (mimeType == null) mimeType = DEFAULT_MIME_TYPE;
+ properties.add(factory.create(JcrLexicon.MIMETYPE, mimeType));
+
+ if (os.toByteArray().length > 0) {
+ // Now put the file's content into the "jcr:data" property ...
+ BinaryFactory binaryFactory = getExecutionContext().getValueFactories().getBinaryFactory();
+ properties.add(factory.create(JcrLexicon.DATA, binaryFactory.create(os.toByteArray())));
+ }
+ }
+ } else {
+ // Determine the corresponding file path for this object ...
String filePath = getPathAsString(requestedPath);
- if (!accessData.getRepositoryRootUrl().equals(request.inWorkspace())) {
+ if (!accessData.getRepositoryRootUrl().equals(workspaceName)) {
filePath = filePath.substring(1);
}
- Path contentPath = pathFactory().create(requestedPath, JcrLexicon.CONTENT);
- Location content = Location.create(contentPath);
- request.addChild(content);
+ if (children != null) {
+ // Not a "jcr:content" child node but rather an nt:file node, so add the child ...
+ Path contentPath = pathFactory().create(requestedPath, JcrLexicon.CONTENT);
+ children.add(Location.create(contentPath));
+ }
+ if (properties != null) {
+ // Now add the properties to "nt:file" ...
+ properties.add(factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE));
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ SVNProperties fileProperties = new SVNProperties();
+ getData(filePath, fileProperties, os);
+ String created = fileProperties.getStringValue(SVNProperty.COMMITTED_DATE);
+ if (created != null) {
+ properties.add(factory.create(JcrLexicon.CREATED, dateFactory.create(created)));
+ }
+ }
}
}
} catch (SVNException e) {
request.setError(e);
}
}
- request.setActualLocationOfNode(myLocation);
- setCacheableInfo(request);
+ return true;
}
/**
* {@inheritDoc}
*
- * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllPropertiesRequest)
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadNodeRequest)
*/
@Override
- public void process( ReadAllPropertiesRequest request ) {
+ public void process( ReadNodeRequest request ) {
logger.trace(request.toString());
-
- // Get the SVNRepository object that represents the workspace ...
- SVNRepository workspaceRoot = getWorkspaceDirectory(request.inWorkspace());
- if (workspaceRoot == null) {
- request.setError(new InvalidWorkspaceException(
- SVNRepositoryConnectorI18n.workspaceDoesNotExist.text(request.inWorkspace())));
- return;
+ List<Location> children = new LinkedList<Location>();
+ List<Property> properties = new LinkedList<Property>();
+ if (readNode(request.inWorkspace(), request.at(), properties, children, request)) {
+ request.addChildren(children);
+ request.addProperties(properties);
+ request.setActualLocationOfNode(request.at());
+ setCacheableInfo(request);
}
+ }
- // Find the existing file for the parent ...
- Location myLocation = request.at();
- Path requestedPath = getPathFor(myLocation, request);
- if (requestedPath.isRoot()) {
- // There are no properties on the root ...
- request.setActualLocationOfNode(myLocation);
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllChildrenRequest)
+ */
+ @Override
+ public void process( ReadAllChildrenRequest request ) {
+ logger.trace(request.toString());
+ List<Location> children = new LinkedList<Location>();
+ if (readNode(request.inWorkspace(), request.of(), null, children, request)) {
+ request.addChildren(children);
+ request.setActualLocationOfNode(request.of());
setCacheableInfo(request);
- return;
}
- try {
+ }
- SVNNodeKind kind = getNodeKind(workspaceRoot, requestedPath, accessData.getRepositoryRootUrl(), request.inWorkspace());
- // Generate the properties for this File object ...
- PropertyFactory factory = getExecutionContext().getPropertyFactory();
- DateTimeFactory dateFactory = getExecutionContext().getValueFactories().getDateFactory();
- // Note that we don't have 'created' timestamps, just last modified, so we'll have to use them
- if (kind == SVNNodeKind.DIR) {
- String directoryPath = getPathAsString(requestedPath);
- if (!accessData.getRepositoryRootUrl().equals(request.inWorkspace())) {
- directoryPath = directoryPath.substring(1);
- }
- request.addProperty(factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FOLDER));
- SVNDirEntry entry = getEntryInfo(workspaceRoot, directoryPath);
- request.addProperty(factory.create(JcrLexicon.LAST_MODIFIED, dateFactory.create(entry.getDate())));
- } else {
- if (requestedPath.getLastSegment().getName().equals(JcrLexicon.CONTENT)) {
- String contentPath = getPathAsString(requestedPath.getParent());
- if (!accessData.getRepositoryRootUrl().equals(request.inWorkspace())) {
- contentPath = contentPath.substring(1);
- }
- SVNDirEntry entry = getEntryInfo(workspaceRoot, contentPath);
- // The request is to get properties of the "jcr:content" child node ...
- request.addProperty(factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.RESOURCE));
- request.addProperty(factory.create(JcrLexicon.LAST_MODIFIED, dateFactory.create(entry.getDate())));
-
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- SVNProperties fileProperties = new SVNProperties();
- getData(contentPath, fileProperties, os);
- String mimeType = fileProperties.getStringValue(SVNProperty.MIME_TYPE);
- if (mimeType == null) mimeType = DEFAULT_MIME_TYPE;
- request.addProperty(factory.create(JcrLexicon.MIMETYPE, mimeType));
-
- if (os.toByteArray().length > 0) {
- // Now put the file's content into the "jcr:data" property ...
- BinaryFactory binaryFactory = getExecutionContext().getValueFactories().getBinaryFactory();
- request.addProperty(factory.create(JcrLexicon.DATA, binaryFactory.create(os.toByteArray())));
- }
-
- } else {
- String filePath = getPathAsString(requestedPath);
- if (!accessData.getRepositoryRootUrl().equals(request.inWorkspace())) {
- filePath = filePath.substring(1);
- }
- // The request is to get properties for the node representing the file
- request.addProperty(factory.create(JcrLexicon.PRIMARY_TYPE, JcrNtLexicon.FILE));
- ByteArrayOutputStream os = new ByteArrayOutputStream();
- SVNProperties fileProperties = new SVNProperties();
- getData(filePath, fileProperties, os);
- String created = fileProperties.getStringValue(SVNProperty.COMMITTED_DATE);
- if (created != null) {
- request.addProperty(factory.create(JcrLexicon.CREATED, dateFactory.create(created)));
- }
- }
- }
- request.setActualLocationOfNode(myLocation);
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.request.processor.RequestProcessor#process(org.jboss.dna.graph.request.ReadAllPropertiesRequest)
+ */
+ @Override
+ public void process( ReadAllPropertiesRequest request ) {
+ logger.trace(request.toString());
+ List<Property> properties = new LinkedList<Property>();
+ if (readNode(request.inWorkspace(), request.at(), properties, null, request)) {
+ request.addProperties(properties);
+ request.setActualLocationOfNode(request.at());
setCacheableInfo(request);
-
- } catch (SVNException e) {
- request.setError(e);
}
}
@@ -626,7 +617,7 @@
String myPath;
if (getPathAsString(requestedPath).trim().equals("/")) {
myPath = getPathAsString(requestedPath);
- } else if (requestedPath.getLastSegment().getName().equals(JcrLexicon.CONTENT)) {
+ } else if (requestedPath.endsWith(JcrLexicon.CONTENT)) {
myPath = getPathAsString(requestedPath.getParent());
} else {
// directory and file
@@ -663,7 +654,7 @@
*
* @param repos
* @param path - the path
- * @return - the {@link SVNDirEntry}.
+ * @return - the {@link SVNDirEntry}, or null if there is no such entry
*/
protected SVNDirEntry getEntryInfo( SVNRepository repos,
String path ) {
@@ -1025,7 +1016,7 @@
assert repositoryRootUrl != null;
assert inWorkspace != null;
// See if the path is a "jcr:content" node ...
- if (path.getLastSegment().getName().equals(JcrLexicon.CONTENT)) {
+ if (path.endsWith(JcrLexicon.CONTENT)) {
// We only want to use the parent path to find the actual file ...
path = path.getParent();
}
Modified: trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryUtil.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryUtil.java 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/extensions/dna-connector-svn/src/main/java/org/jboss/dna/connector/svn/SVNRepositoryUtil.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -1,6 +1,7 @@
package org.jboss.dna.connector.svn;
import java.util.Collection;
+import java.util.Collections;
import org.jboss.dna.graph.connector.RepositorySourceException;
import org.jboss.dna.graph.request.InvalidWorkspaceException;
import org.tmatesoft.svn.core.SVNDirEntry;
@@ -159,16 +160,15 @@
/**
* @param repos
* @param path
- * @return a collect of entry from directory path.
+ * @return a collect of entry from directory path; never null
*/
@SuppressWarnings( "unchecked" )
public static Collection<SVNDirEntry> getDir( SVNRepository repos,
String path ) {
- Collection<SVNDirEntry> entries = null;
try {
return repos.getDir(path, -1, null, (Collection<SVNDirEntry>)null);
} catch (SVNException e) {
- return entries;
+ return Collections.emptyList();
}
}
Added: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java (rev 0)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -0,0 +1,79 @@
+/*
+ * 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.svn;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNull.notNullValue;
+import static org.junit.Assert.assertThat;
+import java.util.Map;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Graph;
+import org.jboss.dna.graph.Location;
+import org.jboss.dna.graph.Node;
+import org.jboss.dna.graph.property.Name;
+import org.jboss.dna.graph.property.Property;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SVNIntegrationTest {
+
+ private ExecutionContext context;
+ private SVNRepositorySource source;
+ private String repositoryUrl;
+ private String[] predefinedWorkspaceNames;
+
+ @Before
+ public void beforeEach() {
+ repositoryUrl = "http://anonsvn.jboss.org/repos/dna/";
+ predefinedWorkspaceNames = new String[] {repositoryUrl + "trunk", repositoryUrl + "tags", repositoryUrl + "branches"};
+ context = new ExecutionContext();
+ source = new SVNRepositorySource();
+ source.setName("svn repository source");
+ source.setRepositoryRootURL(repositoryUrl);
+ source.setUsername("anonymous");
+ source.setPassword("");
+ source.setCreatingWorkspacesAllowed(true);
+ source.setPredefinedWorkspaceNames(predefinedWorkspaceNames);
+ source.setDirectoryForDefaultWorkspace(predefinedWorkspaceNames[0]);
+ source.setCreatingWorkspacesAllowed(false);
+ }
+
+ @Test
+ public void shouldConnectAndReadRootNode() {
+ Graph graph = Graph.create(source, context);
+ Map<Name, Property> properties = graph.getPropertiesByName().on("/");
+ assertThat(properties, is(notNullValue()));
+
+ Node root = graph.getNodeAt("/");
+ assertThat(root, is(notNullValue()));
+ assertThat(root.getLocation(), is(notNullValue()));
+ assertThat(root.getChildren().isEmpty(), is(false));
+ for (Location childLocation : root.getChildren()) {
+ assertThat(childLocation.getPath().getParent().isRoot(), is(true));
+ // Node child = graph.getNodeAt(childLocation);
+ // assertThat(child.getLocation(), is(childLocation));
+ // assertThat(child.getLocation().getPath().getParent().isRoot(), is(true));
+ }
+ }
+}
Property changes on: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNIntegrationTest.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNRepositoryConnectorCreateWorspaceTest.java
===================================================================
--- trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNRepositoryConnectorCreateWorspaceTest.java 2009-08-26 18:10:37 UTC (rev 1174)
+++ trunk/extensions/dna-connector-svn/src/test/java/org/jboss/dna/connector/svn/SVNRepositoryConnectorCreateWorspaceTest.java 2009-08-26 20:43:45 UTC (rev 1175)
@@ -85,4 +85,10 @@
assertThat(workspaceNames.isEmpty(), is(true));
}
+ @Test
+ @Override
+ public void shouldReadTheChildrenOfTheRootNodeInEachWorkspace() {
+ super.shouldReadTheChildrenOfTheRootNodeInEachWorkspace();
+ }
+
}
14 years, 8 months
DNA SVN: r1174 - in trunk: dna-integration-tests and 1 other directories.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-08-26 14:10:37 -0400 (Wed, 26 Aug 2009)
New Revision: 1174
Added:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservationBus.java
trunk/dna-repository/src/main/java/org/jboss/dna/repository/SimpleRepositoryContext.java
Modified:
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObservers.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/NetChangeObserver.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Observable.java
trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/package-info.java
trunk/dna-integration-tests/pom.xml
trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.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
Log:
DNA-451 RepositoryService should dynamically keep its RepositorySource instances in sync with changes to the configuration repository
The RepositoryLibrary and RepositoryService classes were changed so that the RepositoryService now behaves as an Observer for changes to the content in the configuration source. If the configuration content changes, RepositoryService attempts to update the RepositorySource instance(s) that correspond to the changed content. Of course any removed content for a repository source causes the corresponding RepositorySource object to be removed.
RepositoryService does not own the RepositorySource for the configuration, so it cannot register as a listener on its own. Instead, RepositoryService is now an Observer, it must be registered appropriately to receive the events; this is usually done by the code that owns the configuration RepositorySource. In the case of DnaEngine, this was done by using a (new) ObservationBus class (which allows multiple observers on the bus, but the bus is itself an observer so that we have the multiplexing behavior) registered to receive events from the configuration RepositorySource, and to register RepositoryService as an observer on the bus.
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java 2009-08-25 15:04:41 UTC (rev 1173)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObserver.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -30,7 +30,7 @@
/**
* Abstract class that is used to signal that a change set has occurred. This class is typically subclassed by those that wish to
- * observe changes in content, and {@link Observable#register(ChangeObserver) registered} with a {@link Observable}.
+ * observe changes in content, and {@link Observable#register(Observer) registered} with a {@link Observable}.
* <p>
* This class maintains a (weak) reference to the ChangeSource instances with which it is registered. Therefore, the observers
* will not keep a ChangeSource from being garbage collected. And, if a change source is garbage collected, calling
@@ -65,7 +65,7 @@
/**
* Unregister this listener from all {@link Observable sources} that it was registered with. This is preferred over calling
- * {@link Observable#unregister(ChangeObserver)} directly.
+ * {@link Observable#unregister(Observer)} directly.
*/
public void unregister() {
doUnregister();
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObservers.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObservers.java 2009-08-25 15:04:41 UTC (rev 1173)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ChangeObservers.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -46,11 +46,11 @@
/**
* {@inheritDoc}
*
- * @see org.jboss.dna.graph.observe.Observable#register(org.jboss.dna.graph.observe.ChangeObserver)
+ * @see org.jboss.dna.graph.observe.Observable#register(org.jboss.dna.graph.observe.Observer)
*/
- public boolean register( ChangeObserver observer ) {
+ public boolean register( Observer observer ) {
if (observer != null && !shutdown.get() && observers.addIfAbsent(new ObserverReference(observer))) {
- observer.registeredWith(this);
+ if (observer instanceof ChangeObserver) ((ChangeObserver)observer).registeredWith(this);
return true;
}
return false;
@@ -59,11 +59,11 @@
/**
* {@inheritDoc}
*
- * @see org.jboss.dna.graph.observe.Observable#unregister(org.jboss.dna.graph.observe.ChangeObserver)
+ * @see org.jboss.dna.graph.observe.Observable#unregister(org.jboss.dna.graph.observe.Observer)
*/
- public boolean unregister( ChangeObserver observer ) {
+ public boolean unregister( Observer observer ) {
if (observer != null && observers.remove(observer)) {
- observer.unregisteredWith(this);
+ if (observer instanceof ChangeObserver) ((ChangeObserver)observer).unregisteredWith(this);
return true;
}
return false;
@@ -79,7 +79,10 @@
observers.clear();
while (iter.hasNext()) {
ObserverReference reference = iter.next();
- if (reference.get() != null) reference.get().unregisteredWith(this);
+ if (reference.get() != null) {
+ Observer observer = reference.get();
+ if (observer instanceof ChangeObserver) ((ChangeObserver)observer).unregisteredWith(this);
+ }
}
}
}
@@ -102,7 +105,7 @@
public void broadcast( Changes changes ) {
CheckArg.isNotNull(changes, "changes");
for (ObserverReference observerReference : observers) {
- ChangeObserver observer = observerReference.get();
+ Observer observer = observerReference.get();
if (observer == null) {
observers.remove(observerReference);
continue;
@@ -118,10 +121,10 @@
/**
* A {@link WeakReference} implementation that provides a valid
*/
- protected final class ObserverReference extends WeakReference<ChangeObserver> {
+ protected final class ObserverReference extends WeakReference<Observer> {
final int hc;
- protected ObserverReference( ChangeObserver source ) {
+ protected ObserverReference( Observer source ) {
super(source);
this.hc = source.hashCode();
}
@@ -146,12 +149,12 @@
if (obj == this) return true;
if (obj instanceof ObserverReference) {
ObserverReference that = (ObserverReference)obj;
- ChangeObserver thisSource = this.get();
- ChangeObserver thatSource = that.get();
+ Observer thisSource = this.get();
+ Observer thatSource = that.get();
return thisSource == thatSource; // reference equality, not object equality!
}
- if (obj instanceof ChangeObserver) {
- ChangeObserver that = (ChangeObserver)obj;
+ if (obj instanceof Observer) {
+ Observer that = (Observer)obj;
return this.get() == that; // reference equality, not object equality!
}
return false;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/NetChangeObserver.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/NetChangeObserver.java 2009-08-25 15:04:41 UTC (rev 1173)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/NetChangeObserver.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -147,7 +147,7 @@
/**
* Method that is called for each net change.
*
- * @param change
+ * @param change the net change; never null
*/
protected abstract void notify( NetChange change );
@@ -228,13 +228,25 @@
return this.hc;
}
- public boolean includesAll( ChangeType... jcrEventTypes ) {
+ /**
+ * Determine whether this net change includes all of the supplied types.
+ *
+ * @param jcrEventTypes the types to check for
+ * @return true if all of the supplied events are included in this net change, or false otherwise
+ */
+ public boolean includesAllOf( ChangeType... jcrEventTypes ) {
for (ChangeType jcrEventType : jcrEventTypes) {
if (!this.eventTypes.contains(jcrEventType)) return false;
}
return true;
}
+ /**
+ * Determine whether this net change includes any of the supplied types.
+ *
+ * @param jcrEventTypes the types to check for
+ * @return true if any of the supplied events are included in this net change, or false otherwise
+ */
public boolean includes( ChangeType... jcrEventTypes ) {
for (ChangeType jcrEventType : jcrEventTypes) {
if (this.eventTypes.contains(jcrEventType)) return true;
@@ -242,10 +254,6 @@
return false;
}
- public boolean is( ChangeType jcrEventTypes ) {
- return this.eventTypes.contains(jcrEventTypes);
- }
-
public boolean isSameNode( NetChange that ) {
if (that == this) return true;
if (this.hc != that.hc) return false;
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Observable.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Observable.java 2009-08-25 15:04:41 UTC (rev 1173)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/Observable.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -39,7 +39,7 @@
* @return true if the observer was added, or false if the observer was null, if the observer was already registered, or if
* the observer could not be added
*/
- boolean register( ChangeObserver observer );
+ boolean register( Observer observer );
/**
* Unregister the supplied observer. This method does nothing if the observer reference is null.
@@ -48,6 +48,6 @@
* @return true if the observer was removed, or false if the observer was null or if the observer was not registered on this
* source
*/
- boolean unregister( ChangeObserver observer );
+ boolean unregister( Observer observer );
}
Added: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservationBus.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservationBus.java (rev 0)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservationBus.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -0,0 +1,81 @@
+/*
+ * 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.graph.observe;
+
+/**
+ * A simple {@link Observer} that is itself {@link Observable}. This class essentially multiplexes the events from a single
+ * Observable to disseminate each event to multiple Observers.
+ */
+public class ObservationBus implements Observable, Observer {
+ private final ChangeObservers observers = new ChangeObservers();
+
+ public ObservationBus() {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.observe.Observable#register(org.jboss.dna.graph.observe.Observer)
+ */
+ public boolean register( Observer observer ) {
+ return observers.register(observer);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.observe.Observable#unregister(org.jboss.dna.graph.observe.Observer)
+ */
+ public boolean unregister( Observer observer ) {
+ return observers.unregister(observer);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.observe.Observer#notify(org.jboss.dna.graph.observe.Changes)
+ */
+ public void notify( Changes changes ) {
+ if (changes != null) {
+ // Broadcast the changes to the registered observers ...
+ observers.broadcast(changes);
+ }
+ }
+
+ /**
+ * Determine whether this particular bus currently has any observers.
+ *
+ * @return true if there is at least one observer, or false otherwise
+ */
+ public boolean hasObservers() {
+ return !observers.isEmpty();
+ }
+
+ /**
+ * Unregister all registered observers, and mark this as no longer accepting new registered observers.
+ */
+ public void shutdown() {
+ observers.shutdown();
+ }
+}
Property changes on: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/ObservationBus.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
Modified: trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/package-info.java
===================================================================
--- trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/package-info.java 2009-08-25 15:04:41 UTC (rev 1173)
+++ trunk/dna-graph/src/main/java/org/jboss/dna/graph/observe/package-info.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -48,7 +48,7 @@
* <p>
* Components that are to recieve notifications of changes are called <i>observers</i>. To create an observer, simply extend
* the {@link ChangeObserver} abstract class and provide an implementation of the {@link ChangeObserver#notify(Changes)} method.
- * Then, register the observer with an {@link Observable} using its {@link Observable#register(ChangeObserver)} method.
+ * Then, register the observer with an {@link Observable} using its {@link Observable#register(Observer)} method.
* The observer's {@link ChangeObserver#notify(Changes)} method will then be called with the changes that have
* been made to the Observable.
* </p>
@@ -56,7 +56,7 @@
* it was registered. The {@link ChangeObserver} class automatically tracks which {@link Observable} instances it is
* registered with, and calling the observer's {@link ChangeObserver#unregister()} will unregister the observer from
* all of these Observables. Alternatively, an observer can be unregistered from a single Observable using the
- * Observable's {@link Observable#unregister(ChangeObserver)} method.
+ * Observable's {@link Observable#unregister(Observer)} method.
* </p>
* <h3>Changes</h3>
* <p>
Modified: trunk/dna-integration-tests/pom.xml
===================================================================
--- trunk/dna-integration-tests/pom.xml 2009-08-25 15:04:41 UTC (rev 1173)
+++ trunk/dna-integration-tests/pom.xml 2009-08-26 18:10:37 UTC (rev 1174)
@@ -71,6 +71,12 @@
</dependency>
<dependency>
<groupId>org.jboss.dna</groupId>
+ <artifactId>dna-connector-filesystem</artifactId>
+ <version>${pom.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.dna</groupId>
<artifactId>dna-connector-infinispan</artifactId>
<version>${pom.version}</version>
<scope>test</scope>
Modified: trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.java 2009-08-25 15:04:41 UTC (rev 1173)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/DnaEngine.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -46,12 +46,14 @@
import org.jboss.dna.graph.Subgraph;
import org.jboss.dna.graph.connector.RepositoryConnection;
import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
+import org.jboss.dna.graph.connector.RepositoryContext;
import org.jboss.dna.graph.connector.RepositorySource;
import org.jboss.dna.graph.connector.RepositorySourceException;
import org.jboss.dna.graph.mimetype.ExtensionBasedMimeTypeDetector;
import org.jboss.dna.graph.mimetype.MimeTypeDetector;
import org.jboss.dna.graph.mimetype.MimeTypeDetectorConfig;
import org.jboss.dna.graph.mimetype.MimeTypeDetectors;
+import org.jboss.dna.graph.observe.ObservationBus;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.PathExpression;
@@ -102,12 +104,20 @@
detectors.addDetector(new MimeTypeDetectorConfig("ExtensionDetector", "Extension-based MIME type detector",
ExtensionBasedMimeTypeDetector.class));
+ // Create the RepositoryContext that the configuration repository source should use ...
+ ObservationBus configurationChangeBus = new ObservationBus();
+ RepositoryContext configContext = new SimpleRepositoryContext(context, configurationChangeBus, null);
+ final RepositorySource configSource = this.configuration.getRepositorySource();
+ configSource.initialize(configContext);
+
// Create the RepositoryService, pointing it to the configuration repository ...
Path pathToConfigurationRoot = this.configuration.getPath();
String configWorkspaceName = this.configuration.getWorkspace();
- final RepositorySource configSource = this.configuration.getRepositorySource();
repositoryService = new RepositoryService(configSource, configWorkspaceName, pathToConfigurationRoot, context, problems);
+ // Now register the repository service to be notified of changes to the configuration ...
+ configurationChangeBus.register(repositoryService);
+
// Create the sequencing service ...
executorService = new ScheduledThreadPoolExecutor(10); // Use a magic number for now
sequencingService = new SequencingService();
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-08-25 15:04:41 UTC (rev 1173)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryLibrary.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -25,11 +25,11 @@
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -43,10 +43,8 @@
import org.jboss.dna.graph.connector.RepositoryConnectionPool;
import org.jboss.dna.graph.connector.RepositoryContext;
import org.jboss.dna.graph.connector.RepositorySource;
-import org.jboss.dna.graph.observe.ChangeObserver;
-import org.jboss.dna.graph.observe.ChangeObservers;
-import org.jboss.dna.graph.observe.Changes;
import org.jboss.dna.graph.observe.Observable;
+import org.jboss.dna.graph.observe.ObservationBus;
import org.jboss.dna.graph.observe.Observer;
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.repository.service.AbstractServiceAdministrator;
@@ -110,10 +108,10 @@
private final ServiceAdministrator administrator = new Administrator();
private final ReadWriteLock sourcesLock = new ReentrantReadWriteLock();
- private final CopyOnWriteArrayList<RepositoryConnectionPool> pools = new CopyOnWriteArrayList<RepositoryConnectionPool>();
+ private final Map<String, RepositoryConnectionPool> pools = new HashMap<String, RepositoryConnectionPool>();
private RepositoryConnectionFactory delegate;
private final ExecutionContext executionContext;
- private final ObservationBus observationBus = new InMemoryObservationBus();
+ private final ObservationBus observationBus = new ObservationBus();
private final RepositorySource configurationSource;
private final String configurationWorkspaceName;
private final Path pathToConfigurationRoot;
@@ -167,19 +165,26 @@
/**
* {@inheritDoc}
+ * <p>
+ * This can be used to register observers for all of the repository sources managed by this library. The supplied observer
+ * will receive all of the changes originating from these sources.
+ * </p>
*
- * @see org.jboss.dna.graph.observe.Observable#register(org.jboss.dna.graph.observe.ChangeObserver)
+ * @see org.jboss.dna.graph.observe.Observable#register(org.jboss.dna.graph.observe.Observer)
*/
- public boolean register( ChangeObserver observer ) {
+ public boolean register( Observer observer ) {
return observationBus.register(observer);
}
/**
* {@inheritDoc}
+ * <p>
+ * This can be used to unregister observers for all of the repository sources managed by this library.
+ * </p>
*
- * @see org.jboss.dna.graph.observe.Observable#unregister(org.jboss.dna.graph.observe.ChangeObserver)
+ * @see org.jboss.dna.graph.observe.Observable#unregister(org.jboss.dna.graph.observe.Observer)
*/
- public boolean unregister( ChangeObserver observer ) {
+ public boolean unregister( Observer observer ) {
return observationBus.unregister(observer);
}
@@ -212,7 +217,7 @@
// Close all connections to the pools. This is done inside the pools write lock.
try {
this.sourcesLock.readLock().lock();
- for (RepositoryConnectionPool pool : this.pools) {
+ for (RepositoryConnectionPool pool : this.pools.values()) {
pool.shutdown();
}
} finally {
@@ -236,7 +241,7 @@
// Check whether all source pools are shut down. This is done inside the pools write lock.
try {
this.sourcesLock.readLock().lock();
- for (RepositoryConnectionPool pool : this.pools) {
+ for (RepositoryConnectionPool pool : this.pools.values()) {
if (!pool.awaitTermination(timeout, unit)) return false;
}
return true;
@@ -258,7 +263,7 @@
public boolean isTerminating() {
try {
this.sourcesLock.readLock().lock();
- for (RepositoryConnectionPool pool : this.pools) {
+ for (RepositoryConnectionPool pool : this.pools.values()) {
if (pool.isTerminating()) return true;
}
return false;
@@ -276,7 +281,7 @@
public boolean isTerminated() {
try {
this.sourcesLock.readLock().lock();
- for (RepositoryConnectionPool pool : this.pools) {
+ for (RepositoryConnectionPool pool : this.pools.values()) {
if (!pool.isTerminated()) return false;
}
return true;
@@ -291,11 +296,12 @@
* @return the pools
*/
public Collection<String> getSourceNames() {
- Set<String> sourceNames = new HashSet<String>();
- for (RepositoryConnectionPool pool : this.pools) {
- sourceNames.add(pool.getRepositorySource().getName());
+ try {
+ this.sourcesLock.readLock().lock();
+ return Collections.unmodifiableCollection(new HashSet<String>(this.pools.keySet()));
+ } finally {
+ this.sourcesLock.readLock().unlock();
}
- return Collections.unmodifiableCollection(sourceNames);
}
/**
@@ -305,10 +311,15 @@
*/
public Collection<RepositorySource> getSources() {
List<RepositorySource> sources = new LinkedList<RepositorySource>();
- for (RepositoryConnectionPool pool : this.pools) {
- sources.add(pool.getRepositorySource());
+ try {
+ this.sourcesLock.readLock().lock();
+ for (RepositoryConnectionPool pool : this.pools.values()) {
+ sources.add(pool.getRepositorySource());
+ }
+ return Collections.unmodifiableCollection(sources);
+ } finally {
+ this.sourcesLock.readLock().unlock();
}
- return Collections.unmodifiableCollection(sources);
}
/**
@@ -320,14 +331,11 @@
public RepositorySource getSource( String sourceName ) {
try {
this.sourcesLock.readLock().lock();
- for (RepositoryConnectionPool existingPool : this.pools) {
- RepositorySource source = existingPool.getRepositorySource();
- if (source.getName().equals(sourceName)) return source;
- }
+ RepositoryConnectionPool existingPool = this.pools.get(sourceName);
+ return existingPool == null ? null : existingPool.getRepositorySource();
} finally {
this.sourcesLock.readLock().unlock();
}
- return null;
}
/**
@@ -339,14 +347,10 @@
public RepositoryConnectionPool getConnectionPool( String sourceName ) {
try {
this.sourcesLock.readLock().lock();
- for (RepositoryConnectionPool existingPool : this.pools) {
- RepositorySource source = existingPool.getRepositorySource();
- if (source.getName().equals(sourceName)) return existingPool;
- }
+ return this.pools.get(sourceName);
} finally {
this.sourcesLock.readLock().unlock();
}
- return null;
}
/**
@@ -357,68 +361,99 @@
* supplied name.
*/
public boolean addSource( RepositorySource source ) {
+ return addSource(source, false);
+ }
+
+ /**
+ * Add the supplied federated source. This method returns false if the source is null.
+ * <p>
+ * If a source with the same name already exists, it will be replaced only if <code>replaceIfExisting</code> is true. If this
+ * is the case, then the existing source will be removed from the connection pool, and that pool will be
+ * {@link RepositoryConnectionPool#shutdown() shutdown} (allowing any in-use connections to be used and finished normally).
+ * </p>
+ *
+ * @param source the source to add
+ * @param replaceIfExisting true if an existing source should be replaced, or false if this method should return false if
+ * there is already an existing source with the supplied name.
+ * @return true if the source is added, or false if the reference is null or if there is already an existing source with the
+ * supplied name.
+ */
+ public boolean addSource( RepositorySource source,
+ boolean replaceIfExisting ) {
if (source == null) return false;
- try {
- this.sourcesLock.writeLock().lock();
- final String sourceName = source.getName();
- for (RepositoryConnectionPool existingPool : this.pools) {
- if (existingPool.getRepositorySource().getName().equals(sourceName)) return false;
+ final String sourceName = source.getName();
+ if (!replaceIfExisting) {
+ // Don't want to replace existing, so make sure there isn't one already ...
+ try {
+ this.sourcesLock.readLock().lock();
+ if (this.pools.containsKey(sourceName)) return false;
+ } finally {
+ this.sourcesLock.readLock().unlock();
}
- // Create a repository context for this source ...
- final ObservationBus observationBus = this.observationBus;
- RepositoryContext repositoryContext = new RepositoryContext() {
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.connector.RepositoryContext#getExecutionContext()
- */
- public ExecutionContext getExecutionContext() {
- return RepositoryLibrary.this.getExecutionContext();
- }
+ }
+ // Create a repository context for this source ...
+ final ObservationBus observationBus = this.observationBus;
+ RepositoryContext repositoryContext = new RepositoryContext() {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositoryContext#getExecutionContext()
+ */
+ public ExecutionContext getExecutionContext() {
+ return RepositoryLibrary.this.getExecutionContext();
+ }
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.connector.RepositoryContext#getRepositoryConnectionFactory()
- */
- public RepositoryConnectionFactory getRepositoryConnectionFactory() {
- return RepositoryLibrary.this;
- }
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositoryContext#getRepositoryConnectionFactory()
+ */
+ public RepositoryConnectionFactory getRepositoryConnectionFactory() {
+ return RepositoryLibrary.this;
+ }
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.connector.RepositoryContext#getObserver()
- */
- public Observer getObserver() {
- return observationBus.hasObservers() ? observationBus : null;
- }
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositoryContext#getObserver()
+ */
+ public Observer getObserver() {
+ return observationBus.hasObservers() ? observationBus : null;
+ }
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.connector.RepositoryContext#getConfiguration(int)
- */
- public Subgraph getConfiguration( int depth ) {
- Subgraph result = null;
- RepositorySource configSource = getConfigurationSource();
- if (configSource != null) {
- Graph config = Graph.create(configSource, getExecutionContext());
- String workspaceName = getConfigurationWorkspaceName();
- if (workspaceName != null) {
- config.useWorkspace(workspaceName);
- }
- Path configPath = getPathToConfigurationRoot();
- Path sourcePath = getExecutionContext().getValueFactories().getPathFactory().create(configPath,
- sourceName);
- result = config.getSubgraphOfDepth(depth).at(sourcePath);
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositoryContext#getConfiguration(int)
+ */
+ public Subgraph getConfiguration( int depth ) {
+ Subgraph result = null;
+ RepositorySource configSource = getConfigurationSource();
+ if (configSource != null) {
+ Graph config = Graph.create(configSource, getExecutionContext());
+ String workspaceName = getConfigurationWorkspaceName();
+ if (workspaceName != null) {
+ config.useWorkspace(workspaceName);
}
- return result;
+ Path configPath = getPathToConfigurationRoot();
+ Path sourcePath = getExecutionContext().getValueFactories().getPathFactory().create(configPath, sourceName);
+ result = config.getSubgraphOfDepth(depth).at(sourcePath);
}
- };
- source.initialize(repositoryContext);
- RepositoryConnectionPool pool = new RepositoryConnectionPool(source);
- this.pools.add(pool);
+ return result;
+ }
+ };
+ // Do this before we remove the existing pool ...
+ source.initialize(repositoryContext);
+ RepositoryConnectionPool pool = new RepositoryConnectionPool(source);
+ try {
+ this.sourcesLock.writeLock().lock();
+ // Need to first remove any existing one ...
+ RepositoryConnectionPool existingPool = this.pools.remove(sourceName);
+ if (existingPool != null) {
+ // Then shut down the source gracefully (and don't wait) ...
+ existingPool.shutdown();
+ }
+ this.pools.put(sourceName, pool);
return true;
} finally {
this.sourcesLock.writeLock().unlock();
@@ -450,6 +485,32 @@
/**
* Remove from this federated repository the source with the supplied name. This call shuts down the connections in the source
* in an orderly fashion, allowing those connection currently in use to be used and closed normally, but preventing further
+ * connections from being used. However, this method never waits until the connections are all closed, and is equivalent to
+ * calling <code>removeSource(name,0,TimeUnit.SECONDS)</code>.
+ *
+ * @param name the name of the source to be removed
+ * @return the source with the supplied name that was removed, or null if no existing source matching the supplied name could
+ * be found
+ * @see #removeSource(String, long, TimeUnit)
+ */
+ public RepositorySource removeSource( String name ) {
+ try {
+ this.sourcesLock.writeLock().lock();
+ RepositoryConnectionPool existingPool = this.pools.remove(name);
+ if (existingPool != null) {
+ // Then shut down the source gracefully (and don't wait) ...
+ existingPool.shutdown();
+ return existingPool.getRepositorySource();
+ }
+ } finally {
+ this.sourcesLock.writeLock().unlock();
+ }
+ return null;
+ }
+
+ /**
+ * Remove from this federated repository the source with the supplied name. This call shuts down the connections in the source
+ * in an orderly fashion, allowing those connection currently in use to be used and closed normally, but preventing further
* connections from being used.
*
* @param name the name of the source to be removed
@@ -459,18 +520,18 @@
* @return the source with the supplied name that was removed, or null if no existing source matching the supplied name could
* be found
* @throws InterruptedException if the thread is interrupted while awaiting closing of the connections
+ * @see #removeSource(String)
*/
public RepositorySource removeSource( String name,
long timeToAwait,
TimeUnit unit ) throws InterruptedException {
try {
this.sourcesLock.writeLock().lock();
- for (RepositoryConnectionPool existingPool : this.pools) {
- if (existingPool.getRepositorySource().getName().equals(name)) {
- // Shut down the source ...
- existingPool.shutdown();
- if (timeToAwait > 0L) existingPool.awaitTermination(timeToAwait, unit);
- }
+ RepositoryConnectionPool existingPool = this.pools.remove(name);
+ if (existingPool != null) {
+ // Then shut down the source gracefully (and don't wait) ...
+ existingPool.shutdown();
+ if (timeToAwait > 0L) existingPool.awaitTermination(timeToAwait, unit);
return existingPool.getRepositorySource();
}
} finally {
@@ -487,10 +548,8 @@
public RepositoryConnection createConnection( String sourceName ) {
try {
this.sourcesLock.readLock().lock();
- for (RepositoryConnectionPool existingPool : this.pools) {
- RepositorySource source = existingPool.getRepositorySource();
- if (source.getName().equals(sourceName)) return existingPool.getConnection();
- }
+ RepositoryConnectionPool existingPool = this.pools.get(sourceName);
+ if (existingPool != null) return existingPool.getConnection();
RepositoryConnectionFactory delegate = this.delegate;
if (delegate != null) {
return delegate.createConnection(sourceName);
@@ -500,65 +559,4 @@
}
return null;
}
-
- protected interface ObservationBus extends Observable, Observer {
- boolean hasObservers();
-
- void shutdown();
- }
-
- protected class InMemoryObservationBus implements ObservationBus {
- private final ChangeObservers observers = new ChangeObservers();
-
- protected InMemoryObservationBus() {
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.observe.Observable#register(org.jboss.dna.graph.observe.ChangeObserver)
- */
- public boolean register( ChangeObserver observer ) {
- return observers.register(observer);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.observe.Observable#unregister(org.jboss.dna.graph.observe.ChangeObserver)
- */
- public boolean unregister( ChangeObserver observer ) {
- return observers.unregister(observer);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.graph.observe.Observer#notify(org.jboss.dna.graph.observe.Changes)
- */
- public void notify( Changes changes ) {
- if (changes != null) {
- // Broadcast the changes to the registered observers ...
- observers.broadcast(changes);
- }
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.repository.RepositoryLibrary.ObservationBus#hasObservers()
- */
- public boolean hasObservers() {
- return !observers.isEmpty();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.jboss.dna.repository.RepositoryLibrary.ObservationBus#shutdown()
- */
- public void shutdown() {
- observers.shutdown();
- }
- }
}
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-08-25 15:04:41 UTC (rev 1173)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/RepositoryService.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -42,6 +42,9 @@
import org.jboss.dna.graph.Node;
import org.jboss.dna.graph.Subgraph;
import org.jboss.dna.graph.connector.RepositorySource;
+import org.jboss.dna.graph.observe.Changes;
+import org.jboss.dna.graph.observe.NetChangeObserver;
+import org.jboss.dna.graph.observe.Observer;
import org.jboss.dna.graph.property.Name;
import org.jboss.dna.graph.property.Path;
import org.jboss.dna.graph.property.PathFactory;
@@ -58,7 +61,7 @@
* @author Randall Hauch
*/
@ThreadSafe
-public class RepositoryService implements AdministeredService {
+public class RepositoryService implements AdministeredService, Observer {
/**
* The administrative component for this service.
@@ -104,6 +107,7 @@
private final String configurationSourceName;
private final String configurationWorkspaceName;
private final Path pathToConfigurationRoot;
+ private final ConfigurationChangeObserver configurationChangeObserver;
private final Administrator administrator = new Administrator();
private final AtomicBoolean started = new AtomicBoolean(false);
/** The problem sink used when encountering problems while starting repositories */
@@ -141,26 +145,27 @@
this.configurationWorkspaceName = configurationWorkspaceName;
this.context = context;
this.problems = problems;
+ this.configurationChangeObserver = new ConfigurationChangeObserver();
}
/**
* {@inheritDoc}
*/
- public ServiceAdministrator getAdministrator() {
+ public final ServiceAdministrator getAdministrator() {
return this.administrator;
}
/**
* @return configurationSourceName
*/
- public String getConfigurationSourceName() {
+ public final String getConfigurationSourceName() {
return configurationSourceName;
}
/**
* @return configurationWorkspaceName
*/
- public String getConfigurationWorkspaceName() {
+ public final String getConfigurationWorkspaceName() {
return configurationWorkspaceName;
}
@@ -169,14 +174,21 @@
*
* @return the RepositorySource library; never null
*/
- public RepositoryLibrary getRepositoryLibrary() {
+ public final RepositoryLibrary getRepositoryLibrary() {
return sources;
}
/**
+ * @return pathToConfigurationRoot
+ */
+ protected final Path getPathToConfigurationRoot() {
+ return pathToConfigurationRoot;
+ }
+
+ /**
* @return env
*/
- public ExecutionContext getExecutionEnvironment() {
+ public final ExecutionContext getExecutionEnvironment() {
return context;
}
@@ -186,7 +198,7 @@
}
protected synchronized void startService() {
- if (this.started.get() == false) {
+ if (this.started.get() == false) {
// ------------------------------------------------------------------------------------
// Read the configuration ...
// ------------------------------------------------------------------------------------
@@ -211,7 +223,7 @@
} catch (Throwable err) {
throw new FederationException(RepositoryI18n.errorStartingRepositoryService.text(), err);
}
-
+
this.started.set(true);
}
}
@@ -404,4 +416,58 @@
if (obj == this) return true;
return false;
}
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.observe.Observer#notify(org.jboss.dna.graph.observe.Changes)
+ */
+ public void notify( Changes changes ) {
+ // Forward the changes to the net change observer ...
+ this.configurationChangeObserver.notify(changes);
+ }
+
+ protected class ConfigurationChangeObserver extends NetChangeObserver {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.observe.NetChangeObserver#notify(org.jboss.dna.graph.observe.NetChangeObserver.NetChange)
+ */
+ @Override
+ protected void notify( NetChange change ) {
+ if (!getConfigurationSourceName().equals(change.getRepositorySourceName())) return;
+ if (!getConfigurationWorkspaceName().equals(change.getRepositoryWorkspaceName())) return;
+ Path changedPath = change.getPath();
+ Path configPath = getPathToConfigurationRoot();
+ if (!changedPath.isAtOrBelow(getPathToConfigurationRoot())) return;
+ boolean changedNodeIsPotentiallySource = configPath.size() + 1 == changedPath.size();
+
+ // At this point, we know that something inside the configuration changed, so figure out what happened ...
+ if (changedNodeIsPotentiallySource && change.includes(ChangeType.NODE_REMOVED)) {
+ // Then potentially a source with the supplied name has been removed ...
+ String sourceName = changedPath.getLastSegment().getName().getLocalName();
+ getRepositoryLibrary().removeSource(sourceName);
+ } else {
+ // The add/change/remove is either at or below a source, so try to create a new source for it ...
+ Path sourcePath = changedNodeIsPotentiallySource ? changedPath : changedPath.subpath(0, configPath.size() + 1);
+ Problems problems = new SimpleProblems();
+ // Now read the node and create the source ...
+ Graph graph = Graph.create(getConfigurationSourceName(), getRepositoryLibrary(), getExecutionEnvironment());
+ try {
+ String workspaceName = getConfigurationWorkspaceName();
+ if (workspaceName != null) graph.useWorkspace(workspaceName);
+ Map<Name, Property> properties = graph.getPropertiesByName().on(sourcePath);
+ RepositorySource source = createRepositorySource(sourcePath, properties, problems);
+ if (source != null) {
+ // It was the config for a source, so try to add or replace an existing source ...
+ getRepositoryLibrary().addSource(source, true);
+ }
+ } catch (PathNotFoundException e) {
+ // No source was found, and this is okay (since it may just been deleted)...
+ String sourceName = changedPath.getLastSegment().getName().getLocalName();
+ getRepositoryLibrary().removeSource(sourceName);
+ }
+ }
+ }
+ }
}
Added: trunk/dna-repository/src/main/java/org/jboss/dna/repository/SimpleRepositoryContext.java
===================================================================
--- trunk/dna-repository/src/main/java/org/jboss/dna/repository/SimpleRepositoryContext.java (rev 0)
+++ trunk/dna-repository/src/main/java/org/jboss/dna/repository/SimpleRepositoryContext.java 2009-08-26 18:10:37 UTC (rev 1174)
@@ -0,0 +1,88 @@
+/*
+ * JBoss DNA (http://www.jboss.org/dna)
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * See the AUTHORS.txt file in the distribution for a full listing of
+ * individual contributors.
+ *
+ * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
+ * is licensed to you under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * JBoss DNA is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.dna.repository;
+
+import net.jcip.annotations.Immutable;
+import org.jboss.dna.graph.ExecutionContext;
+import org.jboss.dna.graph.Subgraph;
+import org.jboss.dna.graph.connector.RepositoryConnectionFactory;
+import org.jboss.dna.graph.connector.RepositoryContext;
+import org.jboss.dna.graph.observe.Observer;
+
+/**
+ * A simple, immutable {@link RepositoryContext} implementation that uses the references supplied as parameters to the
+ * constructor.
+ */
+@Immutable
+public class SimpleRepositoryContext implements RepositoryContext {
+
+ private final ExecutionContext context;
+ private final Observer observer;
+ private final RepositoryConnectionFactory connectionFactory;
+
+ public SimpleRepositoryContext( ExecutionContext context,
+ Observer observer,
+ RepositoryConnectionFactory connectionFactory ) {
+ this.context = context;
+ this.observer = observer;
+ this.connectionFactory = connectionFactory;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositoryContext#getConfiguration(int)
+ */
+ public Subgraph getConfiguration( int depth ) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositoryContext#getExecutionContext()
+ */
+ public ExecutionContext getExecutionContext() {
+ return context;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositoryContext#getObserver()
+ */
+ public Observer getObserver() {
+ return observer;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.jboss.dna.graph.connector.RepositoryContext#getRepositoryConnectionFactory()
+ */
+ public RepositoryConnectionFactory getRepositoryConnectionFactory() {
+ return connectionFactory;
+ }
+
+}
Property changes on: trunk/dna-repository/src/main/java/org/jboss/dna/repository/SimpleRepositoryContext.java
___________________________________________________________________
Name: svn:keywords
+ Id Revision
Name: svn:eol-style
+ LF
14 years, 8 months
DNA SVN: r1173 - trunk/extensions/dna-sequencer-java.
by dna-commits@lists.jboss.org
Author: rhauch
Date: 2009-08-25 11:04:41 -0400 (Tue, 25 Aug 2009)
New Revision: 1173
Modified:
trunk/extensions/dna-sequencer-java/pom.xml
Log:
DNA-502 Non-integration build does not succeed
The extensions/dna-sequencer-java/pom.xml file was change to remove the (unused and unnecessary) dependency on 'dna-integration-test'. After doing this and clearing my local maven repository, the 'mvn clean install' command now builds successfully (as does 'mvn clean install -P integration'). This fix should resolve the issue.
Modified: trunk/extensions/dna-sequencer-java/pom.xml
===================================================================
--- trunk/extensions/dna-sequencer-java/pom.xml 2009-08-24 18:50:21 UTC (rev 1172)
+++ trunk/extensions/dna-sequencer-java/pom.xml 2009-08-25 15:04:41 UTC (rev 1173)
@@ -44,12 +44,6 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
- <dependency>
- <groupId>org.jboss.dna</groupId>
- <artifactId>dna-integration-tests</artifactId>
- <version>0.6-SNAPSHOT</version>
- <scope>test</scope>
- </dependency>
<!--
Testing (note the scope)
-->
14 years, 8 months