You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ja...@apache.org on 2012/04/03 16:37:55 UTC

svn commit: r1308949 - in /ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui: domain/ vaadin/ vaadin/component/

Author: jawi
Date: Tue Apr  3 14:37:54 2012
New Revision: 1308949

URL: http://svn.apache.org/viewvc?rev=1308949&view=rev
Log:
ACE-247: add a logout button to the WebUI; also cleaned up some deleted/moved domain classes, and added proper license headers.

Removed:
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/AbstractAddWindow.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/NamedArtifactObject.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/NamedDistributionObject.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/NamedFeatureObject.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/NamedTargetObject.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/OBREntry.java
Modified:
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedArtifactObject.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedDistributionObject.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedFeatureObject.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedTargetObject.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/OBREntry.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/Associations.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/LoginWindow.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinClient.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinResourceHandler.java
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/MainActionToolbar.java

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedArtifactObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedArtifactObject.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedArtifactObject.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedArtifactObject.java Tue Apr  3 14:37:54 2012
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.ace.webui.domain;
 
 import org.apache.ace.client.repository.RepositoryObject;

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedDistributionObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedDistributionObject.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedDistributionObject.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedDistributionObject.java Tue Apr  3 14:37:54 2012
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.ace.webui.domain;
 
 import org.apache.ace.client.repository.RepositoryObject;

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedFeatureObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedFeatureObject.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedFeatureObject.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedFeatureObject.java Tue Apr  3 14:37:54 2012
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.ace.webui.domain;
 
 import org.apache.ace.client.repository.RepositoryObject;

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedTargetObject.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedTargetObject.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedTargetObject.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/NamedTargetObject.java Tue Apr  3 14:37:54 2012
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.ace.webui.domain;
 
 import org.apache.ace.client.repository.RepositoryObject;

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/OBREntry.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/OBREntry.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/OBREntry.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/domain/OBREntry.java Tue Apr  3 14:37:54 2012
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.ace.webui.domain;
 
 public class OBREntry {

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/Associations.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/Associations.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/Associations.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/Associations.java Tue Apr  3 14:37:54 2012
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.ace.webui.vaadin;
 
 import java.util.ArrayList;

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/LoginWindow.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/LoginWindow.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/LoginWindow.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/LoginWindow.java Tue Apr  3 14:37:54 2012
@@ -1,24 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 package org.apache.ace.webui.vaadin;
 
 import org.osgi.service.log.LogService;
 
-import com.vaadin.terminal.UserError;
+import com.vaadin.event.ShortcutAction.KeyCode;
 import com.vaadin.ui.Alignment;
 import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.PasswordField;
 import com.vaadin.ui.TextField;
 import com.vaadin.ui.VerticalLayout;
 import com.vaadin.ui.Window;
-import com.vaadin.ui.Button.ClickEvent;
 
-@SuppressWarnings("serial")
+/**
+ * Provides a simple login dialog.
+ */
 public class LoginWindow extends Window {
 
     public interface LoginFunction {
         boolean login(String name, String password);
-    };
+    }
 
     private volatile LogService m_log;
+
     private TextField m_name;
     private PasswordField m_password;
     private Button m_loginButton;
@@ -26,53 +47,81 @@ public class LoginWindow extends Window 
 
     public LoginWindow(final LogService log, final LoginFunction loginFunction) {
         super("Apache ACE Login");
+
         m_log = log;
         m_loginFunction = loginFunction;
+
         setResizable(false);
+        setClosable(false);
         setModal(true);
         setWidth("15em");
 
-        LoginPanel p = new LoginPanel();
-        setContent(p);
-    }
+        m_name = new TextField("Name", "");
+        m_name.setImmediate(true);
 
-    public void closeWindow() {
-        getParent().removeWindow(this);
-    }
+        m_password = new PasswordField("Password", "");
+        m_password.setImmediate(true);
+
+        m_loginButton = new Button("Login");
+        m_loginButton.setImmediate(true);
+        // Allow enter to be used to login directly...
+        m_loginButton.setClickShortcut(KeyCode.ENTER);
+        // Highlight this button as the default one...
+        m_loginButton.addStyleName("primary");
+
+        m_loginButton.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                final Button button = event.getButton();
+                button.setEnabled(false);
+
+                try {
+                    String username = (String) m_name.getValue();
+                    String password = (String) m_password.getValue();
+
+                    if (m_loginFunction.login(username, password)) {
+                        m_log.log(LogService.LOG_INFO, "Apache Ace WebUI succesfull login by user: " + username);
 
-    public class LoginPanel extends VerticalLayout {
-        public LoginPanel() {
-            setSpacing(true);
-            setMargin(true);
-            setClosable(false);
-            setSizeFull();
-            m_name = new TextField("Name", "");
-            m_password = new PasswordField("Password", "");
-            m_loginButton = new Button("Login");
-            addComponent(m_name);
-            addComponent(m_password);
-            addComponent(m_loginButton);
-            setComponentAlignment(m_loginButton, Alignment.BOTTOM_CENTER);
-            m_name.focus();
-            m_name.selectAll();
-            m_loginButton.addListener(new Button.ClickListener() {
-                public void buttonClick(ClickEvent event) {
-                    if (m_loginFunction.login((String) m_name.getValue(),
-                        (String) m_password.getValue())) {
-                        m_log.log(LogService.LOG_INFO,
-                            "Apache Ace WebUI succesfull login by user: " + (String) m_name.getValue());
                         closeWindow();
                     }
                     else {
-                        // TODO provide some feedback, login failed, for now
-                        // don't close the login window
                         m_log.log(LogService.LOG_WARNING, "Apache Ace WebUI invalid username or password entered.");
-                        m_loginButton.setComponentError(new UserError(
-                            "Invalid username or password."));
+
+                        getParent().showNotification("Invalid username or password!");
+                        setRelevantFocus();
                     }
                 }
-            });
-        }
+                finally {
+                    button.setEnabled(true);
+                }
+            }
+        });
+
+        final VerticalLayout content = (VerticalLayout) getContent();
+        content.setSpacing(true);
+        content.setMargin(true);
+        content.setSizeFull();
+
+        content.addComponent(m_name);
+        content.addComponent(m_password);
+        content.addComponent(m_loginButton);
+
+        content.setComponentAlignment(m_loginButton, Alignment.BOTTOM_CENTER);
+
+        setRelevantFocus();
     }
 
+    /**
+     * Gives the username field the current focus.
+     */
+    void setRelevantFocus() {
+        m_name.focus();
+        m_name.selectAll();
+    }
+
+    /**
+     * Closes this login window.
+     */
+    public void closeWindow() {
+        getParent().removeWindow(this);
+    }
 }
\ No newline at end of file

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinClient.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinClient.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinClient.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinClient.java Tue Apr  3 14:37:54 2012
@@ -39,23 +39,22 @@ import org.apache.ace.client.repository.
 import org.apache.ace.client.repository.helper.bundle.BundleHelper;
 import org.apache.ace.client.repository.object.Artifact2FeatureAssociation;
 import org.apache.ace.client.repository.object.ArtifactObject;
-import org.apache.ace.client.repository.object.TargetObject;
-import org.apache.ace.client.repository.object.Feature2DistributionAssociation;
-import org.apache.ace.client.repository.object.FeatureObject;
 import org.apache.ace.client.repository.object.Distribution2TargetAssociation;
 import org.apache.ace.client.repository.object.DistributionObject;
+import org.apache.ace.client.repository.object.Feature2DistributionAssociation;
+import org.apache.ace.client.repository.object.FeatureObject;
+import org.apache.ace.client.repository.object.TargetObject;
 import org.apache.ace.client.repository.repository.Artifact2FeatureAssociationRepository;
 import org.apache.ace.client.repository.repository.ArtifactRepository;
-import org.apache.ace.client.repository.repository.Feature2DistributionAssociationRepository;
-import org.apache.ace.client.repository.repository.FeatureRepository;
 import org.apache.ace.client.repository.repository.Distribution2TargetAssociationRepository;
 import org.apache.ace.client.repository.repository.DistributionRepository;
+import org.apache.ace.client.repository.repository.Feature2DistributionAssociationRepository;
+import org.apache.ace.client.repository.repository.FeatureRepository;
 import org.apache.ace.client.repository.stateful.StatefulTargetObject;
 import org.apache.ace.client.repository.stateful.StatefulTargetRepository;
 import org.apache.ace.test.utils.FileUtils;
 import org.apache.ace.webui.NamedObject;
 import org.apache.ace.webui.UIExtensionFactory;
-import org.apache.ace.webui.domain.OBREntry;
 import org.apache.ace.webui.vaadin.component.MainActionToolbar;
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
@@ -77,7 +76,6 @@ import com.vaadin.event.dd.DropHandler;
 import com.vaadin.event.dd.TargetDetails;
 import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
 import com.vaadin.event.dd.acceptcriteria.Or;
-import com.vaadin.terminal.Sizeable;
 import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
 import com.vaadin.ui.AbstractSelect.VerticalLocationIs;
 import com.vaadin.ui.Button;
@@ -90,7 +88,6 @@ import com.vaadin.ui.ProgressIndicator;
 import com.vaadin.ui.Table;
 import com.vaadin.ui.Table.TableTransferable;
 import com.vaadin.ui.Window;
-import com.vaadin.ui.Window.Notification;
 
 /*
 
@@ -109,11 +106,14 @@ import com.vaadin.ui.Window.Notification
  */
 @SuppressWarnings("serial")
 public class VaadinClient extends com.vaadin.Application {
+    
     public static final String OBJECT_NAME = "name";
     public static final String OBJECT_DESCRIPTION = "description";
 
     private static final long serialVersionUID = 1L;
+    
     private static long SESSION_ID = 12345;
+    
     private static String targetRepo = "target";
     private static String shopRepo = "shop";
     private static String deployRepo = "deployment";
@@ -137,14 +137,10 @@ public class VaadinClient extends com.va
     private volatile RepositoryAdmin m_admin;
     private volatile LogService m_log;
     private String m_sessionID;
-    private volatile List<DistributionObject> m_distributions;
     private ObjectPanel m_artifactsPanel;
     private ObjectPanel m_featuresPanel;
     private ObjectPanel m_distributionsPanel;
     private ObjectPanel m_targetsPanel;
-    private List<ArtifactObject> m_artifacts;
-    private List<FeatureObject> m_features;
-    private List<StatefulTargetObject> m_targets;
     private final Associations m_associations = new Associations();
 
     private GridLayout m_grid;
@@ -212,32 +208,40 @@ public class VaadinClient extends com.va
         setTheme("ace");
         if (!m_dependenciesResolved.get()) {
             final Window message = new Window("Apache ACE");
-            setMainWindow(message);
             message.getContent().setSizeFull();
-            Label richText =
-                new Label(
+            setMainWindow(message);
+            
+            Label richText = new Label(
                     "<h1>Apache ACE User Interface</h1>"
                         + "<p>Due to missing component dependencies on the server, probably due to misconfiguration, "
                         + "the user interface cannot be properly started. Please contact your server administrator. "
                         + "You can retry accessing the user interface by <a href=\"?restartApplication\">following this link</a>.</p>");
-            // TODO we might want to add some more details here as to what's
-            // missing
-            // on the other hand, the user probably can't fix that anyway
             richText.setContentMode(Label.CONTENT_XHTML);
+            
+            // TODO we might want to add some more details here as to what's
+            // missing on the other hand, the user probably can't fix that anyway
             message.addComponent(richText);
             return;
         }
 
         m_mainWindow = new Window("Apache ACE");
-        setMainWindow(m_mainWindow);
         m_mainWindow.getContent().setSizeFull();
+        
+        setMainWindow(m_mainWindow);
 
+        showLoginWindow();
+    }
+
+    /**
+     * Shows the login window on the center of the main window.
+     */
+    private void showLoginWindow() {
         LoginWindow loginWindow = new LoginWindow(m_log, new LoginWindow.LoginFunction() {
             public boolean login(String name, String password) {
                 return VaadinClient.this.login(name, password);
             }
         });
-        m_mainWindow.getWindow().addWindow(loginWindow);
+        m_mainWindow.addWindow(loginWindow);
         loginWindow.center();
     }
 
@@ -471,6 +475,12 @@ public class VaadinClient extends com.va
             protected void doAfterCommit() throws IOException {
                 // Nop
             }
+            
+            @Override
+            protected void doAfterLogout() throws IOException {
+                // Close the application and reload the main window...
+                close();
+            }
 
             private void updateTableData() {
                 m_artifactsPanel.populate();
@@ -796,12 +806,10 @@ public class VaadinClient extends com.va
                 if (item != null) {
                     item.getItemProperty(OBJECT_NAME).setValue(statefulTarget.getID());
                     item.getItemProperty(OBJECT_DESCRIPTION).setValue("");
-                    Button removeLinkButton = new RemoveLinkButton<StatefulTargetObject>(statefulTarget,
-                        m_distributionsPanel, null) {
+                    Button removeLinkButton = new RemoveLinkButton<StatefulTargetObject>(statefulTarget, m_distributionsPanel, null) {
                         @Override
                         protected void removeLinkFromLeft(StatefulTargetObject object, RepositoryObject other) {
-                            List<Distribution2TargetAssociation> associations = object
-                                .getAssociationsWith((DistributionObject) other);
+                            List<Distribution2TargetAssociation> associations = object.getAssociationsWith((DistributionObject) other);
                             for (Distribution2TargetAssociation association : associations) {
                                 m_license2TargetAssociationRepository.remove(association);
                             }
@@ -848,10 +856,8 @@ public class VaadinClient extends com.va
             if (transferable instanceof TableTransferable) {
                 TableTransferable tt = (TableTransferable) transferable;
                 Object fromItemId = tt.getItemId();
-                // get the active selection, but only if we drag from the same
-                // table
-                Set<?> selection = m_associations.isActiveTable(tt.getSourceComponent()) ? m_associations
-                    .getActiveSelection() : null;
+                // get the active selection, but only if we drag from the same table
+                Set<?> selection = m_associations.isActiveTable(tt.getSourceComponent()) ? m_associations.getActiveSelection() : null;
                 if (targetDetails instanceof AbstractSelectTargetDetails) {
                     AbstractSelectTargetDetails ttd = (AbstractSelectTargetDetails) targetDetails;
                     Object toItemId = ttd.getItemIdOver();
@@ -875,11 +881,10 @@ public class VaadinClient extends com.va
                             associateFromRight((String) toItemId, (String) fromItemId);
                         }
                     }
-                    // TODO add to highlighting (it's probably easiest to
-                    // recalculate the whole
-                    // set of related and associated items here, see
-                    // SelectionListener, or to manually
-                    // figure out the changes in all cases
+                    // TODO add to highlighting (it's probably easiest to 
+                    // recalculate the whole set of related and associated 
+                    // items here, see SelectionListener, or to manually figure
+                    // out the changes in all cases
                 }
             }
         }
@@ -1051,14 +1056,6 @@ public class VaadinClient extends com.va
         return m_statefulTargetRepository.get(name);
     }
 
-    private void deleteFeature(String name) {
-        FeatureObject feature = getFeature(name);
-        if (feature != null) {
-            m_featureRepository.remove(feature);
-            // TODO cleanup links?
-        }
-    }
-
     @Override
     public void close() {
         super.close();
@@ -1145,14 +1142,13 @@ public class VaadinClient extends com.va
             }
         }
 
-        private void init(Component component) {
+        public void init(Component component) {
             populate();
             DependencyManager dm = component.getDependencyManager();
             component.add(dm
                 .createServiceDependency()
                 .setInstanceBound(true)
-                .setService(UIExtensionFactory.class,
-                    "(" + UIExtensionFactory.EXTENSION_POINT_KEY + "=" + m_extensionPoint + ")")
+                .setService(UIExtensionFactory.class, "(" + UIExtensionFactory.EXTENSION_POINT_KEY + "=" + m_extensionPoint + ")")
                 .setCallbacks("addExtension", "removeExtension"));
         }
 

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinResourceHandler.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinResourceHandler.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinResourceHandler.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinResourceHandler.java Tue Apr  3 14:37:54 2012
@@ -18,17 +18,16 @@
  */
 package org.apache.ace.webui.vaadin;
 
-import java.io.File;
 import java.io.IOException;
 import java.net.URL;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.osgi.framework.BundleContext;
 import org.osgi.service.http.HttpContext;
 import org.osgi.service.http.HttpService;
 import org.osgi.service.http.NamespaceException;
-import org.osgi.framework.*;
 
 public class VaadinResourceHandler {
     private volatile HttpService m_http;

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/MainActionToolbar.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/MainActionToolbar.java?rev=1308949&r1=1308948&r2=1308949&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/MainActionToolbar.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/MainActionToolbar.java Tue Apr  3 14:37:54 2012
@@ -26,6 +26,7 @@ import org.osgi.service.event.EventHandl
 import com.vaadin.ui.Button;
 import com.vaadin.ui.Button.ClickEvent;
 import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Label;
 import com.vaadin.ui.Window.Notification;
 
 /**
@@ -34,29 +35,25 @@ import com.vaadin.ui.Window.Notification
 public abstract class MainActionToolbar extends GridLayout implements EventHandler {
 
     /**
-     * Provides a button listener for the revert button.
+     * Provides a button listener for the logout button.
      */
-    private final class RevertButtonListener implements Button.ClickListener, ConfirmationDialog.Callback {
-
+    private class LogoutButtonListener implements Button.ClickListener, ConfirmationDialog.Callback {
+        
         /**
          * {@inheritDoc}
          */
         public void buttonClick(ClickEvent event) {
+            final RepositoryAdmin repoAdmin = getRepositoryAdmin();
             try {
-                if (getRepositoryAdmin().isModified()) {
-                    // Revert all changes...
-                    getWindow().addWindow(new ConfirmationDialog("Revert changes?",
-                        "Are you sure you want to overwrite all local changes?", this));
+                if (repoAdmin.isModified() && repoAdmin.isCurrent()) {
+                    getWindow().addWindow(new ConfirmationDialog("Revert changes?", "The repository is changed. Are you sure you want to loose all local changes?", this));
                 }
                 else {
-                    // Nothing to revert...
-                    getWindow().showNotification("Nothing to revert",
-                        "There are no local changes that need to be reverted.",
-                        Notification.TYPE_WARNING_MESSAGE);
+                    logout();
                 }
             }
             catch (IOException e) {
-                handleIOException(e);
+                getWindow().showNotification("Changes not stored", "Failed to store the changes to the server.<br />Reason: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
             }
         }
 
@@ -66,7 +63,7 @@ public abstract class MainActionToolbar 
         public void onDialogResult(String buttonName) {
             if (ConfirmationDialog.YES.equals(buttonName)) {
                 try {
-                    revertChanges();
+                    logout();
                 }
                 catch (IOException e) {
                     handleIOException(e);
@@ -75,29 +72,27 @@ public abstract class MainActionToolbar 
         }
 
         /**
-         * Does the actual revert of changes.
-         * 
-         * @throws IOException in case of problems during I/O exception.
+         * @param e the exception to handle.
          */
-        private void revertChanges() throws IOException {
-            getRepositoryAdmin().revert();
-            doAfterRevert();
+        private void handleIOException(IOException e) {
+            getWindow().showNotification("Warning", "There were errors during the logout procedure.<br />Reason: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
         }
 
         /**
-         * @param e the exception to handle.
+         * Does the actual logout of the user.
+         * 
+         * @throws IOException in case of I/O problems during the logout.
          */
-        private void handleIOException(IOException e) {
-            getWindow().showNotification("Revert failed",
-                "Failed to revert your changes.<br />" + "Reason: " + e.getMessage(),
-                Notification.TYPE_ERROR_MESSAGE);
+        private void logout() throws IOException {
+            getRepositoryAdmin().logout(true /* force */);
+            doAfterLogout();
         }
     }
 
     /**
-     * Provides a button listener for the store button.
+     * Provides a button listener for the retrieve button.
      */
-    private final class StoreButtonListener implements Button.ClickListener {
+    private final class RetrieveButtonListener implements Button.ClickListener, ConfirmationDialog.Callback {
 
         /**
          * {@inheritDoc}
@@ -106,57 +101,67 @@ public abstract class MainActionToolbar 
             final RepositoryAdmin repoAdmin = getRepositoryAdmin();
             try {
                 if (repoAdmin.isModified()) {
-                    if (repoAdmin.isCurrent()) {
-                        commitChanges();
-                    }
-                    else {
-                        getWindow().showNotification("Changes not stored",
-                            "Unable to store your changes; repository changed!", Notification.TYPE_WARNING_MESSAGE);
-                    }
+                    // Warn the user about the possible loss of changes...
+                    getWindow().addWindow(new ConfirmationDialog("Retrieve latest changes?", "The repository is changed. Are you sure you want to loose all local changes?", this));
                 }
                 else {
-                    getWindow().showNotification("Nothing to store",
-                        "There are no changes that can be stored to the repository.",
-                        Notification.TYPE_WARNING_MESSAGE);
+                    retrieveData();
                 }
             }
             catch (IOException e) {
-                getWindow().showNotification("Changes not stored",
-                    "Failed to store the changes to the server.<br />Reason: " + e.getMessage(),
-                    Notification.TYPE_ERROR_MESSAGE);
+                handleIOException(e);
             }
         }
 
         /**
-         * Does the actual commit of changes.
+         * {@inheritDoc}
+         */
+        public void onDialogResult(String buttonName) {
+            if (ConfirmationDialog.YES.equals(buttonName)) {
+                try {
+                    retrieveData();
+                }
+                catch (IOException e) {
+                    handleIOException(e);
+                }
+            }
+        }
+
+        /**
+         * @param e the exception to handle.
+         */
+        private void handleIOException(IOException e) {
+            getWindow().showNotification("Retrieve failed", "Failed to retrieve the data from the server.<br />Reason: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
+        }
+
+        /**
+         * Does the actual retrieval of the latest version.
          * 
-         * @throws IOException in case of I/O problems during the commit.
+         * @throws IOException in case of I/O problems during the retrieve.
          */
-        private void commitChanges() throws IOException {
-            getRepositoryAdmin().commit();
-            doAfterCommit();
+        private void retrieveData() throws IOException {
+            getRepositoryAdmin().checkout();
+            doAfterRetrieve();
         }
     }
-
+    
     /**
-     * Provides a button listener for the retrieve button.
+     * Provides a button listener for the revert button.
      */
-    private final class RetrieveButtonListener implements Button.ClickListener, ConfirmationDialog.Callback {
+    private final class RevertButtonListener implements Button.ClickListener, ConfirmationDialog.Callback {
 
         /**
          * {@inheritDoc}
          */
         public void buttonClick(ClickEvent event) {
-            final RepositoryAdmin repoAdmin = getRepositoryAdmin();
             try {
-                if (repoAdmin.isModified()) {
-                    // Warn the user about the possible loss of changes...
-                    getWindow().addWindow(
-                        new ConfirmationDialog("Retrieve latest changes?",
-                            "The repository is changed. Are you sure you want to loose all local changes?", this));
+                if (getRepositoryAdmin().isModified()) {
+                    // Revert all changes...
+                    getWindow().addWindow(new ConfirmationDialog("Revert changes?", "Are you sure you want to overwrite all local changes?", this));
                 }
                 else {
-                    retrieveData();
+                    // Nothing to revert...
+                    getWindow().showNotification("Nothing to revert", "There are no local changes that need to be reverted.", Notification.TYPE_WARNING_MESSAGE);
                 }
             }
             catch (IOException e) {
@@ -170,7 +175,7 @@ public abstract class MainActionToolbar 
         public void onDialogResult(String buttonName) {
             if (ConfirmationDialog.YES.equals(buttonName)) {
                 try {
-                    retrieveData();
+                    revertChanges();
                 }
                 catch (IOException e) {
                     handleIOException(e);
@@ -179,34 +184,74 @@ public abstract class MainActionToolbar 
         }
 
         /**
-         * Does the actual retrieval of the latest version.
+         * @param e the exception to handle.
+         */
+        private void handleIOException(IOException e) {
+            getWindow().showNotification("Revert failed", "Failed to revert your changes.<br />Reason: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
+        }
+
+        /**
+         * Does the actual revert of changes.
          * 
-         * @throws IOException in case of I/O problems during the retrieve.
+         * @throws IOException in case of problems during I/O exception.
          */
-        private void retrieveData() throws IOException {
-            getRepositoryAdmin().checkout();
-            doAfterRetrieve();
+        private void revertChanges() throws IOException {
+            getRepositoryAdmin().revert();
+            doAfterRevert();
         }
+    }
+
+    /**
+     * Provides a button listener for the store button.
+     */
+    private final class StoreButtonListener implements Button.ClickListener {
 
         /**
-         * @param e the exception to handle.
+         * {@inheritDoc}
          */
-        private void handleIOException(IOException e) {
-            getWindow().showNotification("Retrieve failed", "Failed to retrieve the data from the server.<br />" +
-                "Reason: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
+        public void buttonClick(ClickEvent event) {
+            final RepositoryAdmin repoAdmin = getRepositoryAdmin();
+            try {
+                if (repoAdmin.isModified()) {
+                    if (repoAdmin.isCurrent()) {
+                        commitChanges();
+                    }
+                    else {
+                        getWindow().showNotification("Changes not stored", "Unable to store your changes; repository changed!", Notification.TYPE_WARNING_MESSAGE);
+                    }
+                }
+                else {
+                    getWindow().showNotification("Nothing to store", "There are no changes that can be stored to the repository.", Notification.TYPE_WARNING_MESSAGE);
+                }
+            }
+            catch (IOException e) {
+                getWindow().showNotification("Changes not stored", "Failed to store the changes to the server.<br />Reason: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
+            }
+        }
+
+        /**
+         * Does the actual commit of changes.
+         * 
+         * @throws IOException in case of I/O problems during the commit.
+         */
+        private void commitChanges() throws IOException {
+            getRepositoryAdmin().commit();
+            doAfterCommit();
         }
     }
 
     private Button m_retrieveButton;
     private Button m_storeButton;
     private Button m_revertButton;
+    private Button m_logoutButton;
 
     /**
      * Creates a new {@link MainActionToolbar} instance.
      */
     public MainActionToolbar() {
-        super(3, 1);
+        super(5, 1);
 
+        setWidth("100%");
         setSpacing(true);
 
         initComponent();
@@ -217,16 +262,14 @@ public abstract class MainActionToolbar 
      */
     public void handleEvent(org.osgi.service.event.Event event) {
         String topic = event.getTopic();
-        if (RepositoryAdmin.TOPIC_STATUSCHANGED.equals(topic) || RepositoryAdmin.TOPIC_REFRESH.equals(topic)
-            || RepositoryAdmin.TOPIC_LOGIN.equals(topic)) {
+        if (RepositoryAdmin.TOPIC_STATUSCHANGED.equals(topic) || RepositoryAdmin.TOPIC_REFRESH.equals(topic) || RepositoryAdmin.TOPIC_LOGIN.equals(topic)) {
 
             boolean modified = false;
             try {
                 modified = getRepositoryAdmin().isModified();
             }
             catch (IOException e) {
-                getWindow().showNotification("Communication failed!", "Failed to communicate with the server.<br />" +
-                    "Reason: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
+                getWindow().showNotification("Communication failed!", "Failed to communicate with the server.<br />Reason: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
             }
 
             m_storeButton.setEnabled(modified);
@@ -235,23 +278,18 @@ public abstract class MainActionToolbar 
     }
 
     /**
-     * @return a repository admin instance, never <code>null</code>.
-     */
-    protected abstract RepositoryAdmin getRepositoryAdmin();
-
-    /**
-     * Called after a revert has taken place, allows additional UI-updates to be performed.
+     * Called after a commit/store has taken place, allows additional UI-updates to be performed.
      * 
      * @throws IOException
      */
-    protected abstract void doAfterRevert() throws IOException;
+    protected abstract void doAfterCommit() throws IOException;
 
     /**
-     * Called after a commit/store has taken place, allows additional UI-updates to be performed.
+     * Called after a logout has taken place, allows additional UI-updates to be performed.
      * 
      * @throws IOException
      */
-    protected abstract void doAfterCommit() throws IOException;
+    protected abstract void doAfterLogout() throws IOException;
 
     /**
      * Called after a retrieve has taken place, allows additional UI-updates to be performed.
@@ -259,6 +297,18 @@ public abstract class MainActionToolbar 
      * @throws IOException
      */
     protected abstract void doAfterRetrieve() throws IOException;
+    
+    /**
+     * Called after a revert has taken place, allows additional UI-updates to be performed.
+     * 
+     * @throws IOException
+     */
+    protected abstract void doAfterRevert() throws IOException;
+
+    /**
+     * @return a repository admin instance, never <code>null</code>.
+     */
+    protected abstract RepositoryAdmin getRepositoryAdmin();
 
     /**
      * Initializes this component.
@@ -275,5 +325,16 @@ public abstract class MainActionToolbar 
         m_revertButton = new Button("Revert");
         m_revertButton.addListener(new RevertButtonListener());
         addComponent(m_revertButton, 2, 0);
+        
+        Label spacer = new Label(" ");
+        addComponent(spacer, 3, 0);
+        
+        m_logoutButton = new Button("Logout");
+        m_logoutButton.addListener(new LogoutButtonListener());
+        addComponent(m_logoutButton, 4, 0);
+
+        // Ensure the spacer gets all the excessive room, causing the logout 
+        // button to appear at the right side of the screen....
+        setColumnExpandRatio(3, 5);
     }
 }