ace-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r1310280 [1/2] - in /ace/trunk/ace-webui-vaadin/src/main: java/org/apache/ace/webui/vaadin/ java/org/apache/ace/webui/vaadin/component/ resources/VAADIN/themes/reindeer/ resources/VAADIN/themes/reindeer/icons/
Date Fri, 06 Apr 2012 11:28:02 GMT
Author: jawi
Date: Fri Apr  6 11:28:01 2012
New Revision: 1310280

URL: http://svn.apache.org/viewvc?rev=1310280&view=rev
Log:
ACE-248: implemented state icons for artifacts, features, distributions and targets. Also refactored the various object-panels into concrete subclasses to make their code a bit more maintainable. This also allowed for better event handling regarding state changes of repository objects.

Added:
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/ArtifactsPanel.java   (with props)
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java   (with props)
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/DistributionsPanel.java   (with props)
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/FeaturesPanel.java   (with props)
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/RemoveAssociationHandler.java   (with props)
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/TargetsPanel.java   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/resource_workingstate_changed.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/resource_workingstate_new.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/resource_workingstate_removed.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/resource_workingstate_unchanged.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_provisioning_failed.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_provisioning_idle.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_provisioning_inprogress.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_provisioning_ok.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_registered.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_store_approved.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_store_new.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_store_new_old.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_store_unapproved.png   (with props)
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/icons/target_unregistered.png   (with props)
Modified:
    ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/EditWindow.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/VaadinServlet.java
    ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/reindeer/styles.css

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/EditWindow.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/EditWindow.java?rev=1310280&r1=1310279&r2=1310280&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/EditWindow.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/EditWindow.java Fri Apr  6 11:28:01 2012
@@ -19,6 +19,8 @@
 package org.apache.ace.webui.vaadin;
 
 import com.vaadin.ui.*;
+import com.vaadin.ui.Button.ClickEvent;
+
 import org.apache.ace.webui.NamedObject;
 import org.apache.ace.webui.UIExtensionFactory;
 import org.apache.ace.webui.domain.NamedTargetObject;
@@ -27,78 +29,116 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+/**
+ * Provides a generic editor for repository objects.
+ */
 public class EditWindow extends Window {
-    private final Window m_main;
-    private TextField m_name;
 
-    public EditWindow(final NamedObject object, Window main, List<UIExtensionFactory> factories) {
-        m_main = main;
+    private final TextField m_name;
+    private final TextField m_description;
+
+    /**
+     * @param object
+     * @param factories
+     */
+    public EditWindow(final NamedObject object, List<UIExtensionFactory> factories) {
         setModal(true);
         setCaption("Edit " + object.getName());
         setWidth("500px");
 
-        VerticalLayout layout = (VerticalLayout) getContent();
-        layout.setMargin(true);
-        layout.setSpacing(true);
-
-        m_name = new TextField("name");
-        final TextField description = new TextField("description");
-
-        m_name.setValue(object.getName());
-        description.setValue(object.getDescription());
-
-        layout.addComponent(m_name);
-        layout.addComponent(description);
+        m_name = new TextField("Name", object.getName());
+        m_name.setReadOnly(object instanceof NamedTargetObject);
+        m_name.setWidth("100%");
+
+        m_description = new TextField("Description", object.getDescription());
+        m_description.setWidth("100%");
+
+        VerticalLayout fields = new VerticalLayout();
+        fields.setSpacing(true);
+        fields.addComponent(m_name);
+        fields.addComponent(m_description);
 
         TabSheet tabs = new TabSheet();
         tabs.setHeight("350px");
+        tabs.setWidth("100%");
+        tabs.setVisible(!factories.isEmpty());
+
         Map<String, Object> context = new HashMap<String, Object>();
         context.put("object", object);
+
         for (UIExtensionFactory factory : factories) {
             try {
-                com.vaadin.ui.Component component = factory.create(context);
-                tabs.addTab(component);
-            } catch (Throwable ex) {
+                tabs.addTab(factory.create(context));
+            }
+            catch (Throwable ex) {
                 // We ignore extension factories that throw exceptions
                 // TODO: log this or something
                 ex.printStackTrace();
             }
         }
-        layout.addComponent(tabs);
 
-        Button close = new Button("Ok", new Button.ClickListener() {
-            // inline click-listener
+        Button okButton = new Button("Ok", new Button.ClickListener() {
             public void buttonClick(Button.ClickEvent event) {
-                // close the window by removing it from the parent window
-                getParent().removeWindow(EditWindow.this);
                 if (object instanceof NamedTargetObject) {
                     // do nothing
                 }
                 else {
-                    object.setDescription((String) description.getValue());
+                    object.setDescription((String) m_description.getValue());
                 }
+
+                closeDialog();
             }
         });
+
+        Button cancelButton = new Button("Cancel", new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                closeDialog();
+            }
+        });
+
+        HorizontalLayout buttonBar = new HorizontalLayout();
+        buttonBar.setSpacing(true);
+        buttonBar.addComponent(okButton);
+        buttonBar.addComponent(cancelButton);
+
+        VerticalLayout layout = (VerticalLayout) getContent();
+        layout.setMargin(true);
+        layout.setSpacing(true);
+        layout.addComponent(fields);
+        layout.addComponent(tabs);
+        layout.addComponent(buttonBar);
+
         // The components added to the window are actually added to the window's
         // layout; you can use either. Alignments are set using the layout
-        layout.addComponent(close);
-        layout.setComponentAlignment(close, Alignment.BOTTOM_RIGHT);
+        layout.setComponentAlignment(buttonBar, Alignment.BOTTOM_RIGHT);
     }
 
-    public void show() {
+    /**
+     * @param parent
+     */
+    public void show(Window parent) {
         if (getParent() != null) {
             // window is already showing
-            m_main.getWindow().showNotification("Window is already open");
-        } else {
-            // Open the subwindow by adding it to the parent
-            // window
-            m_main.getWindow().addWindow(this);
+            parent.showNotification("Window is already open!");
+        }
+        else {
+            parent.addWindow(this);
         }
         setRelevantFocus();
     }
 
+    /**
+     * Closes this dialog by removing it from the parent window.
+     */
+    void closeDialog() {
+        // close the window by removing it from the parent window
+        getParent().removeWindow(this);
+    }
+
+    /**
+     * Sets the focus to the name field.
+     */
     private void setRelevantFocus() {
         m_name.focus();
     }
 }
-

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=1310280&r1=1310279&r2=1310280&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 Fri Apr  6 11:28:01 2012
@@ -20,18 +20,13 @@ package org.apache.ace.webui.vaadin;
 
 import java.io.File;
 import java.io.IOException;
-import java.lang.ref.WeakReference;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.apache.ace.client.repository.ObjectRepository;
 import org.apache.ace.client.repository.RepositoryAdmin;
 import org.apache.ace.client.repository.RepositoryAdminLoginContext;
 import org.apache.ace.client.repository.RepositoryObject;
@@ -53,13 +48,14 @@ import org.apache.ace.client.repository.
 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.vaadin.component.ArtifactsPanel;
+import org.apache.ace.webui.vaadin.component.DistributionsPanel;
+import org.apache.ace.webui.vaadin.component.FeaturesPanel;
 import org.apache.ace.webui.vaadin.component.MainActionToolbar;
+import org.apache.ace.webui.vaadin.component.TargetsPanel;
 import org.apache.felix.dm.Component;
 import org.apache.felix.dm.DependencyManager;
 import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
 import org.osgi.service.event.EventConstants;
 import org.osgi.service.event.EventHandler;
 import org.osgi.service.log.LogService;
@@ -67,10 +63,6 @@ import org.osgi.service.useradmin.Author
 import org.osgi.service.useradmin.User;
 import org.osgi.service.useradmin.UserAdmin;
 
-import com.vaadin.data.Item;
-import com.vaadin.data.Property;
-import com.vaadin.event.ItemClickEvent;
-import com.vaadin.event.ItemClickEvent.ItemClickListener;
 import com.vaadin.event.Transferable;
 import com.vaadin.event.dd.DragAndDropEvent;
 import com.vaadin.event.dd.DropHandler;
@@ -89,7 +81,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;
 
 /*
 
@@ -108,9 +99,6 @@ 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;
     
@@ -122,9 +110,6 @@ public class VaadinClient extends com.va
     private static String customerName = "apache";
     private static String endpoint = "/repository";
 
-    private URL m_aceHost;
-    private URL m_obrUrl;
-
     private volatile DependencyManager m_manager;
     private volatile BundleContext m_context;
     private volatile SessionFactory m_sessionFactory;
@@ -133,29 +118,34 @@ public class VaadinClient extends com.va
     private volatile FeatureRepository m_featureRepository;
     private volatile DistributionRepository m_distributionRepository;
     private volatile StatefulTargetRepository m_statefulTargetRepository;
-    private volatile Artifact2FeatureAssociationRepository m_artifact2GroupAssociationRepository;
-    private volatile Feature2DistributionAssociationRepository m_group2LicenseAssociationRepository;
-    private volatile Distribution2TargetAssociationRepository m_license2TargetAssociationRepository;
+    private volatile Artifact2FeatureAssociationRepository m_artifact2featureAssociationRepository;
+    private volatile Feature2DistributionAssociationRepository m_feature2distributionAssociationRepository;
+    private volatile Distribution2TargetAssociationRepository m_distribution2targetAssociationRepository;
     private volatile RepositoryAdmin m_admin;
     private volatile LogService m_log;
+    
     private String m_sessionID;
-    private ObjectPanel m_artifactsPanel;
-    private ObjectPanel m_featuresPanel;
-    private ObjectPanel m_distributionsPanel;
-    private ObjectPanel m_targetsPanel;
-    private final Associations m_associations = new Associations();
-
+    private ArtifactsPanel m_artifactsPanel;
+    private FeaturesPanel m_featuresPanel;
+    private DistributionsPanel m_distributionsPanel;
+    private TargetsPanel m_targetsPanel;
     private GridLayout m_grid;
-
     private boolean m_dynamicRelations = true;
     private File m_sessionDir; // private folder for session info
-    private final AtomicBoolean m_dependenciesResolved = new AtomicBoolean(false);
     private HorizontalLayout m_artifactToolbar;
     private Button m_featureToolbar;
     private Button m_distributionToolbar;
     private Button m_targetToolbar;
     private Window m_mainWindow;
 
+    private final URL m_aceHost;
+    private final URL m_obrUrl;
+    
+    private final Associations m_associations = new Associations();
+    private final AtomicBoolean m_dependenciesResolved = new AtomicBoolean(false);
+
+    private ProgressIndicator m_progress;
+
     // basic session ID generator
     private static long generateSessionID() {
         return SESSION_ID++;
@@ -193,11 +183,12 @@ public class VaadinClient extends com.va
     // @formatter:on
 
     public void start() {
-        System.out.println("Starting " + m_sessionID);
+        m_log.log(LogService.LOG_INFO, "Starting session #" + m_sessionID);
         m_dependenciesResolved.set(true);
     }
 
     public void stop() {
+        m_log.log(LogService.LOG_INFO, "Stopping session #" + m_sessionID);
         m_dependenciesResolved.set(false);
     }
 
@@ -208,6 +199,7 @@ public class VaadinClient extends com.va
 
     public void init() {
         setTheme("ace");
+        
         if (!m_dependenciesResolved.get()) {
             final Window message = new Window("Apache ACE");
             message.getContent().setSizeFull();
@@ -225,7 +217,7 @@ public class VaadinClient extends com.va
             message.addComponent(richText);
             return;
         }
-
+        
         m_mainWindow = new Window("Apache ACE");
         m_mainWindow.getContent().setSizeFull();
         
@@ -308,12 +300,27 @@ public class VaadinClient extends com.va
             m_grid.addComponent(m_targetsPanel, count, 2);
             m_grid.addComponent(m_targetToolbar, count, 1);
         }
+        
+        // Wire up all panels so they have the correct associations...
+        m_artifactsPanel.setLeftTable(null);
+        m_artifactsPanel.setRightTable(m_featuresPanel);
+        
+        m_featuresPanel.setLeftTable(m_artifactsPanel);
+        m_featuresPanel.setRightTable(m_distributionsPanel);
+        
+        m_distributionsPanel.setLeftTable(m_featuresPanel);
+        m_distributionsPanel.setRightTable(m_targetsPanel);
+        
+        m_targetsPanel.setLeftTable(m_distributionsPanel);
+        m_targetsPanel.setRightTable(null);
 
         m_grid.setRowExpandRatio(2, 1.0f);
 
-        ProgressIndicator progress = new ProgressIndicator(0f);
-        progress.setPollingInterval(500);
-        m_grid.addComponent(progress, 0, 3);
+        m_progress = new ProgressIndicator(0f);
+        m_progress.setStyleName("invisible");
+        m_progress.setPollingInterval(500);
+        
+        m_grid.addComponent(m_progress, 0, 3);
 
         m_artifactsPanel.addListener(m_associations.createSelectionListener(m_artifactsPanel, m_artifactRepository,
             new Class[] {}, new Class[] { FeatureObject.class, DistributionObject.class, TargetObject.class },
@@ -345,10 +352,10 @@ public class VaadinClient extends com.va
                     if (m_dynamicRelations) {
                         Map<String, String> properties = new HashMap<String, String>();
                         properties.put(BundleHelper.KEY_ASSOCIATION_VERSIONSTATEMENT, "0.0.0");
-                        m_artifact2GroupAssociationRepository.create(artifact, properties, getFeature(right), null);
+                        m_artifact2featureAssociationRepository.create(artifact, properties, getFeature(right), null);
                     }
                     else {
-                        m_artifact2GroupAssociationRepository.create(artifact, getFeature(right));
+                        m_artifact2featureAssociationRepository.create(artifact, getFeature(right));
                     }
                 }
             }
@@ -366,23 +373,23 @@ public class VaadinClient extends com.va
                     if (m_dynamicRelations) {
                         Map<String, String> properties = new HashMap<String, String>();
                         properties.put(BundleHelper.KEY_ASSOCIATION_VERSIONSTATEMENT, "0.0.0");
-                        m_artifact2GroupAssociationRepository.create(artifact, properties, getFeature(right), null);
+                        m_artifact2featureAssociationRepository.create(artifact, properties, getFeature(right), null);
                     }
                     else {
-                        m_artifact2GroupAssociationRepository.create(artifact, getFeature(right));
+                        m_artifact2featureAssociationRepository.create(artifact, getFeature(right));
                     }
                 }
             }
 
             @Override
             protected void associateFromRight(String left, String right) {
-                m_group2LicenseAssociationRepository.create(getFeature(left), getDistribution(right));
+                m_feature2distributionAssociationRepository.create(getFeature(left), getDistribution(right));
             }
         });
         m_distributionsPanel.setDropHandler(new AssociationDropHandler(m_featuresPanel, m_targetsPanel) {
             @Override
             protected void associateFromLeft(String left, String right) {
-                m_group2LicenseAssociationRepository.create(getFeature(left), getDistribution(right));
+                m_feature2distributionAssociationRepository.create(getFeature(left), getDistribution(right));
             }
 
             @Override
@@ -392,7 +399,7 @@ public class VaadinClient extends com.va
                     target.register();
                     target.setAutoApprove(true);
                 }
-                m_license2TargetAssociationRepository.create(getDistribution(left), target.getTargetObject());
+                m_distribution2targetAssociationRepository.create(getDistribution(left), target.getTargetObject());
             }
         });
         m_targetsPanel.setDropHandler(new AssociationDropHandler(m_distributionsPanel, (Table) null) {
@@ -403,7 +410,7 @@ public class VaadinClient extends com.va
                     target.register();
                     target.setAutoApprove(true);
                 }
-                m_license2TargetAssociationRepository.create(getDistribution(left), target.getTargetObject());
+                m_distribution2targetAssociationRepository.create(getDistribution(left), target.getTargetObject());
             }
 
             @Override
@@ -411,10 +418,11 @@ public class VaadinClient extends com.va
             }
         });
 
-        addListener(m_artifactsPanel, ArtifactObject.TOPIC_ALL);
-        addListener(m_featuresPanel, FeatureObject.TOPIC_ALL);
-        addListener(m_distributionsPanel, DistributionObject.TOPIC_ALL);
-        addListener(m_targetsPanel, StatefulTargetObject.TOPIC_ALL);
+        addListener(m_artifactsPanel, ArtifactObject.TOPIC_ALL, RepositoryAdmin.TOPIC_STATUSCHANGED);
+        addListener(m_featuresPanel, FeatureObject.TOPIC_ALL, RepositoryAdmin.TOPIC_STATUSCHANGED);
+        addListener(m_distributionsPanel, DistributionObject.TOPIC_ALL, RepositoryAdmin.TOPIC_STATUSCHANGED);
+        addListener(m_targetsPanel, StatefulTargetObject.TOPIC_ALL, RepositoryAdmin.TOPIC_STATUSCHANGED);
+
         m_mainWindow.addComponent(m_grid);
     }
 
@@ -446,13 +454,16 @@ public class VaadinClient extends com.va
         }
     }
 
-    private void addListener(final Object implementation, final String topic) {
-        m_manager.add(m_manager.createComponent().setInterface(EventHandler.class.getName(), new Properties() {
-            {
-                put(EventConstants.EVENT_TOPIC, topic);
-                put(EventConstants.EVENT_FILTER, "(" + SessionFactory.SERVICE_SID + "=" + m_sessionID + ")");
-            }
-        }).setImplementation(implementation));
+    private void addListener(final Object implementation, final String... topics) {
+        Properties props = new Properties();
+        props.put(EventConstants.EVENT_TOPIC, topics);
+        props.put(EventConstants.EVENT_FILTER, "(" + SessionFactory.SERVICE_SID + "=" + m_sessionID + ")");
+        // @formatter:off
+        m_manager.add(
+            m_manager.createComponent()
+                .setInterface(EventHandler.class.getName(), props)
+                .setImplementation(implementation));
+        // @formatter:on
     }
 
     private GridLayout createToolbar() {
@@ -474,7 +485,7 @@ public class VaadinClient extends com.va
 
             @Override
             protected void doAfterCommit() throws IOException {
-                // Nop
+                updateTableData();
             }
             
             @Override
@@ -494,359 +505,90 @@ public class VaadinClient extends com.va
         return mainActionToolbar;
     }
 
-    private ObjectPanel createArtifactsPanel(Window main) {
-        return new ObjectPanel(m_associations, "Artifact", UIExtensionFactory.EXTENSION_POINT_VALUE_ARTIFACT, main,
-            true) {
-            @Override
-            protected RepositoryObject getFromId(String id) {
-                return getArtifact(id);
-            }
-
-            public void populate() {
-                removeAllItems();
-                for (ArtifactObject artifact : m_artifactRepository.get()) {
-                    add(artifact);
-                }
-            }
-
-            public void handleEvent(org.osgi.service.event.Event event) {
-                ArtifactObject artifact = (ArtifactObject) event.getProperty(ArtifactObject.EVENT_ENTITY);
-                String topic = (String) event.getProperty(EventConstants.EVENT_TOPIC);
-                if (ArtifactObject.TOPIC_ADDED.equals(topic)) {
-                    add(artifact);
-                }
-                if (ArtifactObject.TOPIC_REMOVED.equals(topic)) {
-                    remove(artifact);
-                }
-                if (ArtifactObject.TOPIC_CHANGED.equals(topic)) {
-                    change(artifact);
-                }
-            }
-
-            private void add(ArtifactObject artifact) {
-                String resourceProcessorPID = artifact.getAttribute(BundleHelper.KEY_RESOURCE_PROCESSOR_PID);
-                if (resourceProcessorPID != null) {
-                    // if it's a resource processor we don't add it to our list,
-                    // as resource processors don't
-                    // show up there (you can query for them separately)
-
-                    return;
-                }
-                Item item = addItem(artifact.getDefinition());
-                if (item != null) {
-                    item.getItemProperty(OBJECT_NAME).setValue(artifact.getName());
-                    item.getItemProperty(OBJECT_DESCRIPTION).setValue(artifact.getDescription());
-                    HorizontalLayout buttons = new HorizontalLayout();
-                    Button removeLinkButton = new RemoveLinkButton<ArtifactObject>(artifact, null, m_featuresPanel) {
-                        @Override
-                        protected void removeLinkFromLeft(ArtifactObject object, RepositoryObject other) {
-                        }
+    private ArtifactsPanel createArtifactsPanel(Window main) {
+        return new ArtifactsPanel(m_associations) {
 
-                        @Override
-                        protected void removeLinkFromRight(ArtifactObject object, RepositoryObject other) {
-                            List<Artifact2FeatureAssociation> associations = object
-                                .getAssociationsWith((FeatureObject) other);
-                            for (Artifact2FeatureAssociation association : associations) {
-                                m_artifact2GroupAssociationRepository.remove(association);
-                            }
-                            m_associations.removeAssociatedItem(object);
-                            m_table.requestRepaint();
-                        }
-                    };
-                    buttons.addComponent(removeLinkButton);
-                    buttons.addComponent(new RemoveItemButton(artifact, m_artifactRepository));
-                    item.getItemProperty(ACTIONS).setValue(buttons);
-                }
+            @Override
+            protected ArtifactRepository getRepository() {
+                return m_artifactRepository;
             }
-
-            private void change(ArtifactObject artifact) {
-                Item item = getItem(artifact.getDefinition());
-                if (item != null) {
-                    item.getItemProperty(OBJECT_DESCRIPTION).setValue(artifact.getDescription());
-                }
+            
+            @Override
+            protected RepositoryAdmin getRepositoryAdmin() {
+                return m_admin;
             }
-
-            private void remove(ArtifactObject artifact) {
-                removeItem(artifact.getDefinition());
+            
+            @Override
+            protected void removeAssociation(Artifact2FeatureAssociation association) {
+                m_artifact2featureAssociationRepository.remove(association);
             }
         };
     }
 
-    private ObjectPanel createFeaturesPanel(Window main) {
-        return new ObjectPanel(m_associations, "Feature", UIExtensionFactory.EXTENSION_POINT_VALUE_FEATURE, main, true) {
+    private FeaturesPanel createFeaturesPanel(Window main) {
+        return new FeaturesPanel(m_associations) {
             @Override
-            protected RepositoryObject getFromId(String id) {
-                return getFeature(id);
-            }
-
-            public void populate() {
-                removeAllItems();
-                for (FeatureObject feature : m_featureRepository.get()) {
-                    add(feature);
-                }
-            }
-
-            public void handleEvent(org.osgi.service.event.Event event) {
-                FeatureObject feature = (FeatureObject) event.getProperty(FeatureObject.EVENT_ENTITY);
-                String topic = (String) event.getProperty(EventConstants.EVENT_TOPIC);
-                if (FeatureObject.TOPIC_ADDED.equals(topic)) {
-                    add(feature);
-                }
-                if (FeatureObject.TOPIC_REMOVED.equals(topic)) {
-                    remove(feature);
-                }
-                if (FeatureObject.TOPIC_CHANGED.equals(topic)) {
-                    change(feature);
-                }
+            protected FeatureRepository getRepository() {
+                return m_featureRepository;
             }
-
-            private void add(FeatureObject feature) {
-                Item item = addItem(feature.getDefinition());
-                if (item != null) {
-                    item.getItemProperty(OBJECT_NAME).setValue(feature.getName());
-                    item.getItemProperty(OBJECT_DESCRIPTION).setValue(feature.getDescription());
-                    Button removeLinkButton = new RemoveLinkButton<FeatureObject>(feature, m_artifactsPanel,
-                        m_distributionsPanel) {
-                        @Override
-                        protected void removeLinkFromLeft(FeatureObject object, RepositoryObject other) {
-                            List<Artifact2FeatureAssociation> associations = object
-                                .getAssociationsWith((ArtifactObject) other);
-                            for (Artifact2FeatureAssociation association : associations) {
-                                m_artifact2GroupAssociationRepository.remove(association);
-                            }
-                            m_associations.removeAssociatedItem(object);
-                            m_table.requestRepaint();
-                        }
-
-                        @Override
-                        protected void removeLinkFromRight(FeatureObject object, RepositoryObject other) {
-                            List<Feature2DistributionAssociation> associations = object
-                                .getAssociationsWith((DistributionObject) other);
-                            for (Feature2DistributionAssociation association : associations) {
-                                m_group2LicenseAssociationRepository.remove(association);
-                            }
-                            m_associations.removeAssociatedItem(object);
-                            m_table.requestRepaint();
-                        }
-                    };
-                    HorizontalLayout buttons = new HorizontalLayout();
-                    buttons.addComponent(removeLinkButton);
-                    buttons.addComponent(new RemoveItemButton(feature, m_featureRepository));
-                    item.getItemProperty(ACTIONS).setValue(buttons);
-                }
+            
+            @Override
+            protected RepositoryAdmin getRepositoryAdmin() {
+                return m_admin;
             }
-
-            private void change(FeatureObject go) {
-                Item item = getItem(go.getDefinition());
-                if (item != null) {
-                    item.getItemProperty(OBJECT_DESCRIPTION).setValue(go.getDescription());
-                }
+            
+            @Override
+            protected void removeAssocation(Artifact2FeatureAssociation association) {
+                m_artifact2featureAssociationRepository.remove(association);
             }
-
-            private void remove(FeatureObject go) {
-                removeItem(go.getDefinition());
+            
+            @Override
+            protected void removeAssocation(Feature2DistributionAssociation association) {
+                m_feature2distributionAssociationRepository.remove(association);
             }
         };
     }
 
-    public abstract class RemoveLinkButton<REPO_OBJECT extends RepositoryObject> extends Button {
-        // TODO generify?
-        public RemoveLinkButton(final REPO_OBJECT object, final ObjectPanel toLeft, final ObjectPanel toRight) {
-            super("-");
-            setStyleName("small");
-            addListener(new Button.ClickListener() {
-                public void buttonClick(ClickEvent event) {
-                    Set<?> selection = m_associations.getActiveSelection();
-                    if (selection != null) {
-                        if (m_associations.isActiveTable(toLeft)) {
-                            for (Object item : selection) {
-                                RepositoryObject selected = m_associations.lookupInActiveSelection(item);
-                                removeLinkFromLeft(object, selected);
-                            }
-                        }
-                        else if (m_associations.isActiveTable(toRight)) {
-                            for (Object item : selection) {
-                                RepositoryObject selected = m_associations.lookupInActiveSelection(item);
-                                removeLinkFromRight(object, selected);
-                            }
-                        }
-                    }
-                }
-            });
-        }
-
-        protected abstract void removeLinkFromLeft(REPO_OBJECT object, RepositoryObject other);
-
-        protected abstract void removeLinkFromRight(REPO_OBJECT object, RepositoryObject other);
-    }
-
-    public class RemoveItemButton extends Button {
-        public RemoveItemButton(final RepositoryObject object, final ObjectRepository repository) {
-            super("x");
-            setStyleName("small");
-            
-            addListener(new Button.ClickListener() {
-                public void buttonClick(ClickEvent event) {
-                    try {
-                        repository.remove(object);
-                    }
-                    catch (Exception e) {
-                        // ACE-246: notify user when the removal failed!
-                        getWindow().showNotification("Failed to remove item!", "<br/>Reason: " + e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
-                    }
-                }
-            });
-        }
-    }
-
-    private ObjectPanel createDistributionsPanel(Window main) {
-        return new ObjectPanel(m_associations, "Distribution", UIExtensionFactory.EXTENSION_POINT_VALUE_DISTRIBUTION,
-            main, true) {
-            @Override
-            protected RepositoryObject getFromId(String id) {
-                return getDistribution(id);
-            }
-
-            public void populate() {
-                removeAllItems();
-                for (DistributionObject distribution : m_distributionRepository.get()) {
-                    add(distribution);
-                }
-            }
+    private DistributionsPanel createDistributionsPanel(Window main) {
+        return new DistributionsPanel(m_associations) {
 
-            public void handleEvent(org.osgi.service.event.Event event) {
-                DistributionObject distribution = (DistributionObject) event.getProperty(DistributionObject.EVENT_ENTITY);
-                String topic = (String) event.getProperty(EventConstants.EVENT_TOPIC);
-                if (DistributionObject.TOPIC_ADDED.equals(topic)) {
-                    add(distribution);
-                }
-                if (DistributionObject.TOPIC_REMOVED.equals(topic)) {
-                    remove(distribution);
-                }
-                if (DistributionObject.TOPIC_CHANGED.equals(topic)) {
-                    change(distribution);
-                }
+            @Override
+            protected DistributionRepository getRepository() {
+                return m_distributionRepository;
             }
-
-            private void add(DistributionObject distribution) {
-                Item item = addItem(distribution.getDefinition());
-                if (item != null) {
-                    item.getItemProperty(OBJECT_NAME).setValue(distribution.getName());
-                    item.getItemProperty(OBJECT_DESCRIPTION).setValue(distribution.getDescription());
-                    Button removeLinkButton = new RemoveLinkButton<DistributionObject>(distribution, m_featuresPanel, m_targetsPanel) {
-                        @Override
-                        protected void removeLinkFromLeft(DistributionObject object, RepositoryObject other) {
-                            List<Feature2DistributionAssociation> associations = object
-                                .getAssociationsWith((FeatureObject) other);
-                            for (Feature2DistributionAssociation association : associations) {
-                                m_group2LicenseAssociationRepository.remove(association);
-                            }
-                            m_associations.removeAssociatedItem(object);
-                            m_table.requestRepaint();
-                        }
-
-                        @Override
-                        protected void removeLinkFromRight(DistributionObject object, RepositoryObject other) {
-                            List<Distribution2TargetAssociation> associations = object
-                                .getAssociationsWith((TargetObject) other);
-                            for (Distribution2TargetAssociation association : associations) {
-                                m_license2TargetAssociationRepository.remove(association);
-                            }
-                            m_associations.removeAssociatedItem(object);
-                            m_table.requestRepaint();
-                        }
-                    };
-                    HorizontalLayout buttons = new HorizontalLayout();
-                    buttons.addComponent(removeLinkButton);
-                    buttons.addComponent(new RemoveItemButton(distribution, m_distributionRepository));
-                    item.getItemProperty(ACTIONS).setValue(buttons);
-                }
+            
+            @Override
+            protected RepositoryAdmin getRepositoryAdmin() {
+                return m_admin;
             }
-
-            private void change(DistributionObject distribution) {
-                Item item = getItem(distribution.getDefinition());
-                if (item != null) {
-                    item.getItemProperty(OBJECT_DESCRIPTION).setValue(distribution.getDescription());
-                }
+            
+            @Override
+            protected void removeAssocation(Distribution2TargetAssociation association) {
+                m_distribution2targetAssociationRepository.remove(association);
             }
-
-            private void remove(DistributionObject distribution) {
-                removeItem(distribution.getDefinition());
+            
+            @Override
+            protected void removeAssocation(Feature2DistributionAssociation association) {
+                m_feature2distributionAssociationRepository.remove(association);                
             }
         };
     }
 
-    private ObjectPanel createTargetsPanel(Window main) {
-        return new ObjectPanel(m_associations, "Target", UIExtensionFactory.EXTENSION_POINT_VALUE_TARGET, main, true) {
-            private RemoveItemButton m_deleteButton;
-            
+    private TargetsPanel createTargetsPanel(Window main) {
+        return new TargetsPanel(m_associations) {
             @Override
-            protected RepositoryObject getFromId(String id) {
-                return getTarget(id);
-            }
-
-            public void populate() {
-                removeAllItems();
-                for (StatefulTargetObject statefulTarget : m_statefulTargetRepository.get()) {
-                    add(statefulTarget);
-                }
-            }
-
-            public void handleEvent(org.osgi.service.event.Event event) {
-                StatefulTargetObject statefulTarget = (StatefulTargetObject) event.getProperty(StatefulTargetObject.EVENT_ENTITY);
-                String topic = (String) event.getProperty(EventConstants.EVENT_TOPIC);
-                if (StatefulTargetObject.TOPIC_ADDED.equals(topic)) {
-                    add(statefulTarget);
-                }
-                if (StatefulTargetObject.TOPIC_REMOVED.equals(topic)) {
-                    remove(statefulTarget);
-                }
-                if (StatefulTargetObject.TOPIC_CHANGED.equals(topic)) {
-                    change(statefulTarget);
-                }
-            }
-
-            private void add(StatefulTargetObject statefulTarget) {
-                Item item = addItem(statefulTarget.getDefinition());
-                if (item != null) {
-                    item.getItemProperty(OBJECT_NAME).setValue(statefulTarget.getID());
-                    item.getItemProperty(OBJECT_DESCRIPTION).setValue("");
-                    Button removeLinkButton = new RemoveLinkButton<StatefulTargetObject>(statefulTarget, m_distributionsPanel, null) {
-                        @Override
-                        protected void removeLinkFromLeft(StatefulTargetObject object, RepositoryObject other) {
-                            List<Distribution2TargetAssociation> associations = object.getAssociationsWith((DistributionObject) other);
-                            for (Distribution2TargetAssociation association : associations) {
-                                m_license2TargetAssociationRepository.remove(association);
-                            }
-                            m_associations.removeAssociatedItem(object);
-                            m_table.requestRepaint();
-                        }
-
-                        @Override
-                        protected void removeLinkFromRight(StatefulTargetObject object, RepositoryObject other) {
-                        }
-                    };
-                    m_deleteButton = new RemoveItemButton(statefulTarget, m_statefulTargetRepository);
-                    m_deleteButton.setEnabled(statefulTarget.isRegistered());
-
-                    HorizontalLayout buttons = new HorizontalLayout();
-                    buttons.addComponent(removeLinkButton);
-                    buttons.addComponent(m_deleteButton);
-                    item.getItemProperty(ACTIONS).setValue(buttons);
-                }
+            protected StatefulTargetRepository getRepository() {
+                return m_statefulTargetRepository;
             }
-
-            private void change(StatefulTargetObject statefulTarget) {
-                Item item = getItem(statefulTarget.getDefinition());
-                if (item != null) {
-                    item.getItemProperty(OBJECT_DESCRIPTION).setValue("");
-
-                    m_deleteButton.setEnabled(statefulTarget.isRegistered());
-                }
+            
+            @Override
+            protected RepositoryAdmin getRepositoryAdmin() {
+                return m_admin;
             }
-
-            private void remove(StatefulTargetObject statefulTarget) {
-                removeItem(statefulTarget.getDefinition());
+            
+            @Override
+            protected void removeAssocation(Distribution2TargetAssociation association) {
+                m_distribution2targetAssociationRepository.remove(association);
             }
         };
     }
@@ -1072,150 +814,7 @@ public class VaadinClient extends com.va
         // when the session times out
         // TODO: clean up the ace client session?
     }
-    
-    private static class UIExtensionFactoryHolder implements Comparable<UIExtensionFactoryHolder> {
-        private final ServiceReference m_serviceRef;
-        private final WeakReference<UIExtensionFactory> m_extensionFactory;
-        
-        public UIExtensionFactoryHolder(ServiceReference serviceRef, UIExtensionFactory extensionFactory) {
-            m_serviceRef = serviceRef;
-            m_extensionFactory = new WeakReference<UIExtensionFactory>(extensionFactory);
-        }
-
-        public int compareTo(UIExtensionFactoryHolder o) {
-            ServiceReference thatServiceRef = o.m_serviceRef;
-            ServiceReference thisServiceRef = m_serviceRef;
-            // Sort in reverse order so that the highest rankings come first...
-            return thatServiceRef.compareTo(thisServiceRef);
-        }
-        
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj == null) {
-                return false;
-            }
-            if (!(obj instanceof UIExtensionFactoryHolder)) {
-                return false;
-            }
-            UIExtensionFactoryHolder other = (UIExtensionFactoryHolder) obj;
-            return m_serviceRef.equals(other.m_serviceRef);
-        }
-        
-        /**
-         * @return the {@link UIExtensionFactory}, can be <code>null</code> if it has been GC'd before this method call.
-         */
-        public UIExtensionFactory getUIExtensionFactory() {
-            return m_extensionFactory.get();
-        }
-
-        @Override
-        public int hashCode() {
-            return m_serviceRef.hashCode() ^ m_extensionFactory.hashCode();
-        }
-    }
-    
-    public abstract class ObjectPanel extends Table implements EventHandler {
-        public static final String ACTIONS = "actions";
-        
-        protected final Table m_table;
-        protected final Associations m_associations;
-
-        private final List<UIExtensionFactoryHolder> m_extensionFactories;
-        private final String m_extensionPoint;
-
-        public ObjectPanel(Associations associations, final String name, String extensionPoint, final Window main, final boolean hasEdit) {
-            super(name + "s");
-
-            m_table = this;
-            m_extensionFactories = new ArrayList<UIExtensionFactoryHolder>();
-            m_associations = associations;
-            m_extensionPoint = extensionPoint;
-
-            addContainerProperty(OBJECT_NAME, String.class, null);
-            addContainerProperty(OBJECT_DESCRIPTION, String.class, null);
-            addContainerProperty(ACTIONS, HorizontalLayout.class, null);
-
-            setSizeFull();
-            setCellStyleGenerator(m_associations.createCellStyleGenerator());
-            setSelectable(true);
-            setMultiSelect(true);
-            setImmediate(true);
-            setDragMode(TableDragMode.MULTIROW);
-
-            if (hasEdit) {
-                addListener(new ItemClickListener() {
-                    public void itemClick(ItemClickEvent event) {
-                        if (event.isDoubleClick()) {
-                            String itemId = (String) event.getItemId();
-                            RepositoryObject object = getFromId(itemId);
-                            NamedObject namedObject = m_associations.getNamedObject(object);
-                            showEditWindow(namedObject, main);
-                        }
-                    }
-                });
-            }
-        }
-
-        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 + ")")
-                .setCallbacks("addExtension", "removeExtension"));
-        }
-
-        public void addExtension(ServiceReference ref, UIExtensionFactory factory) {
-        	synchronized (m_extensionFactories) {
-        		m_extensionFactories.add(new UIExtensionFactoryHolder(ref, factory));
-			}
-            populate();
-        }
-
-        public void removeExtension(ServiceReference ref, UIExtensionFactory factory) {
-        	synchronized (m_extensionFactories) {
-        		m_extensionFactories.remove(new UIExtensionFactoryHolder(ref, factory));
-        	}
-            populate();
-        }
-
-        private void showEditWindow(NamedObject object, Window main) {
-            List<UIExtensionFactory> extensions = getExtensionFactories();
-            new EditWindow(object, main, extensions).show();
-        }
-
-        /**
-         * @return a list of current extension factories, properly ordered, never <code>null</code>.
-         */
-        private List<UIExtensionFactory> getExtensionFactories() {
-            List<UIExtensionFactory> extensions;
-            synchronized (m_extensionFactories) {
-                // Sort the list of extension factories...
-                Collections.sort(m_extensionFactories);
-                
-                // Walk through the holders and fetch the extension factories one by one...
-                extensions = new ArrayList<UIExtensionFactory>(m_extensionFactories.size());
-                for (UIExtensionFactoryHolder holder : m_extensionFactories) {
-                    UIExtensionFactory extensionFactory = holder.getUIExtensionFactory();
-                    // Make sure only to use non-GCd factories...
-                    if (extensionFactory != null) {
-                        extensions.add(extensionFactory);
-                    }
-                }
-            }
-            return extensions;
-        }
-
-        public abstract void populate();
-
-        protected abstract RepositoryObject getFromId(String id);
-    }
-
+     
     private void showAddArtifactDialog() {
         final AddArtifactWindow featureWindow = new AddArtifactWindow(m_sessionDir, m_obrUrl) {
             @Override

Modified: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinServlet.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinServlet.java?rev=1310280&r1=1310279&r2=1310280&view=diff
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinServlet.java (original)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinServlet.java Fri Apr  6 11:28:01 2012
@@ -37,7 +37,9 @@ import java.util.Dictionary;
 
 public class VaadinServlet extends AbstractApplicationServlet implements ManagedService {
     private static final long serialVersionUID = 1L;
+    
     public static final String PID = "org.apache.ace.webui.vaadin";
+    
     public static final String ACE_HOST = "aceHost";
     public static final String OBR_URL = "obrUrl";
 
@@ -74,7 +76,6 @@ public class VaadinServlet extends Abstr
     }
 
     public void updated(Dictionary dictionary) throws ConfigurationException {
-        System.out.println("There's a config! "+ dictionary);
         if (dictionary != null) {
             URL aceHost;
             try {

Added: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/ArtifactsPanel.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/ArtifactsPanel.java?rev=1310280&view=auto
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/ArtifactsPanel.java (added)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/ArtifactsPanel.java Fri Apr  6 11:28:01 2012
@@ -0,0 +1,122 @@
+/*
+ * 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.component;
+
+import java.util.List;
+
+import org.apache.ace.client.repository.RepositoryAdmin;
+import org.apache.ace.client.repository.RepositoryObject;
+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.FeatureObject;
+import org.apache.ace.client.repository.repository.ArtifactRepository;
+import org.apache.ace.webui.UIExtensionFactory;
+import org.apache.ace.webui.vaadin.Associations;
+
+import com.vaadin.data.Item;
+
+/**
+ *
+ */
+public abstract class ArtifactsPanel extends BaseObjectPanel<ArtifactObject, ArtifactRepository> {
+
+    /**
+     * @param associations
+     */
+    public ArtifactsPanel(Associations associations) {
+        super(associations, "Artifact", UIExtensionFactory.EXTENSION_POINT_VALUE_ARTIFACT, true);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void add(ArtifactObject artifact) {
+        String resourceProcessorPID = artifact.getAttribute(BundleHelper.KEY_RESOURCE_PROCESSOR_PID);
+        if (resourceProcessorPID != null) {
+            // if it's a resource processor we don't add it to our list, as
+            // resource processors don't show up there (you can query for them
+            // separately)
+            return;
+        }
+        Item item = addItem(artifact.getDefinition());
+        if (item != null) {
+            populateItem(artifact, item);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void doHandleEvent(String topic, ArtifactObject artifact, org.osgi.service.event.Event event) {
+        if (ArtifactObject.TOPIC_ADDED.equals(topic)) {
+            add(artifact);
+        }
+        if (ArtifactObject.TOPIC_REMOVED.equals(topic)) {
+            remove(artifact);
+        }
+        if (ArtifactObject.TOPIC_CHANGED.equals(topic) || RepositoryAdmin.TOPIC_STATUSCHANGED.equals(topic)) {
+            update(artifact);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean doRemoveLeftSideAssociation(ArtifactObject object, RepositoryObject other) {
+        return false;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean doRemoveRightSideAssociation(ArtifactObject object, RepositoryObject other) {
+        List<Artifact2FeatureAssociation> associations = object.getAssociationsWith((FeatureObject) other);
+        for (Artifact2FeatureAssociation association : associations) {
+            removeAssociation(association);
+        }
+        return true;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean isSupportedEntity(RepositoryObject entity) {
+        return entity instanceof ArtifactObject;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void populateItem(ArtifactObject artifact, Item item) {
+        item.getItemProperty(WORKING_STATE_ICON).setValue(getWorkingStateIcon(artifact));
+        item.getItemProperty(OBJECT_NAME).setValue(artifact.getName());
+        item.getItemProperty(OBJECT_DESCRIPTION).setValue(artifact.getDescription());
+        item.getItemProperty(ACTIONS).setValue(createActionButtons(artifact));
+    }
+
+    /**
+     * @param association
+     */
+    protected abstract void removeAssociation(Artifact2FeatureAssociation association);
+}

Propchange: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/ArtifactsPanel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java?rev=1310280&view=auto
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java (added)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java Fri Apr  6 11:28:01 2012
@@ -0,0 +1,592 @@
+/*
+ * 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.component;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ace.client.repository.ObjectRepository;
+import org.apache.ace.client.repository.RepositoryAdmin;
+import org.apache.ace.client.repository.RepositoryObject;
+import org.apache.ace.client.repository.RepositoryObject.WorkingState;
+import org.apache.ace.webui.NamedObject;
+import org.apache.ace.webui.UIExtensionFactory;
+import org.apache.ace.webui.vaadin.Associations;
+import org.apache.ace.webui.vaadin.EditWindow;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.event.EventHandler;
+
+import com.vaadin.data.Item;
+import com.vaadin.event.ItemClickEvent;
+import com.vaadin.event.ItemClickEvent.ItemClickListener;
+import com.vaadin.terminal.Resource;
+import com.vaadin.terminal.ThemeResource;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Embedded;
+import com.vaadin.ui.HorizontalLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Window.Notification;
+
+/**
+ * Provides a custom table for displaying artifacts, features and so on.
+ */
+abstract class BaseObjectPanel<REPO_OBJ extends RepositoryObject, REPO extends ObjectRepository<REPO_OBJ>> extends
+    Table implements EventHandler, RemoveAssociationHandler<REPO_OBJ> {
+
+    /**
+     * Provides a generic remove item button.
+     */
+    private static class RemoveItemButton extends Button {
+        public RemoveItemButton(final RepositoryObject object, final ObjectRepository repository) {
+            super("x");
+            setStyleName("small");
+
+            addListener(new Button.ClickListener() {
+                public void buttonClick(ClickEvent event) {
+                    try {
+                        repository.remove(object);
+                    }
+                    catch (Exception e) {
+                        // ACE-246: notify user when the removal failed!
+                        getWindow().showNotification("Failed to remove item!", "<br/>Reason: " + e.getMessage(),
+                            Notification.TYPE_ERROR_MESSAGE);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Provides a generic remove-link (or association) button.
+     */
+    private class RemoveLinkButton<REPO_OBJECT extends RepositoryObject> extends Button {
+        public RemoveLinkButton(final REPO_OBJECT object, final Table toLeft, final Table toRight,
+            final RemoveAssociationHandler<REPO_OBJECT> removeHandler) {
+            super("-");
+            setStyleName("small");
+
+            addListener(new Button.ClickListener() {
+                public void buttonClick(ClickEvent event) {
+                    Set<?> selection = m_associations.getActiveSelection();
+                    if (selection != null) {
+                        if (m_associations.isActiveTable(toLeft)) {
+                            for (Object item : selection) {
+                                RepositoryObject selected = m_associations.lookupInActiveSelection(item);
+                                removeHandler.removeLeftSideAssociation(object, selected);
+                            }
+                        }
+                        else if (m_associations.isActiveTable(toRight)) {
+                            for (Object item : selection) {
+                                RepositoryObject selected = m_associations.lookupInActiveSelection(item);
+                                removeHandler.removeRightSideAssocation(object, selected);
+                            }
+                        }
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Provides a small container for {@link UIExtensionFactory} instances.
+     */
+    private static class UIExtensionFactoryHolder implements Comparable<UIExtensionFactoryHolder> {
+        private final ServiceReference m_serviceRef;
+        private final WeakReference<UIExtensionFactory> m_extensionFactory;
+
+        public UIExtensionFactoryHolder(ServiceReference serviceRef, UIExtensionFactory extensionFactory) {
+            m_serviceRef = serviceRef;
+            m_extensionFactory = new WeakReference<UIExtensionFactory>(extensionFactory);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public int compareTo(UIExtensionFactoryHolder other) {
+            ServiceReference thatServiceRef = other.m_serviceRef;
+            ServiceReference thisServiceRef = m_serviceRef;
+            // Sort in reverse order so that the highest rankings come first...
+            return thatServiceRef.compareTo(thisServiceRef);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (!(obj instanceof UIExtensionFactoryHolder)) {
+                return false;
+            }
+            UIExtensionFactoryHolder other = (UIExtensionFactoryHolder) obj;
+            return m_serviceRef.equals(other.m_serviceRef);
+        }
+
+        /**
+         * @return the {@link UIExtensionFactory}, can be <code>null</code> if it has been GC'd before this method call.
+         */
+        public UIExtensionFactory getUIExtensionFactory() {
+            return m_extensionFactory.get();
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int hashCode() {
+            return m_serviceRef.hashCode() ^ m_extensionFactory.hashCode();
+        }
+    }
+
+    protected static final String WORKING_STATE_ICON = "workStateIcon";
+    protected static final String OBJECT_NAME = "name";
+    protected static final String OBJECT_DESCRIPTION = "description";
+    protected static final String ACTIONS = "actions";
+
+    protected static final int ICON_HEIGHT = 16;
+    protected static final int ICON_WIDTH = 16;
+
+    private final Associations m_associations;
+    private final List<UIExtensionFactoryHolder> m_extensionFactories;
+    private final String m_extensionPoint;
+
+    private Button m_removeLinkButton;
+    private Button m_deleteButton;
+
+    private Table m_leftTable;
+    private Table m_rightTable;
+
+    /**
+     * Creates a new {@link BaseObjectPanel} instance.
+     * 
+     * @param associations the associations for this panel;
+     * @param name the name of this panel;
+     * @param extensionPoint the extension point to listen for;
+     * @param hasEdit <code>true</code> if double clicking an row in this table should show an editor, <code>false</code> to disallow editing.
+     */
+    public BaseObjectPanel(Associations associations, final String name, String extensionPoint, final boolean hasEdit) {
+        super(name + "s");
+
+        m_extensionFactories = new ArrayList<UIExtensionFactoryHolder>();
+        m_associations = associations;
+        m_extensionPoint = extensionPoint;
+
+        defineTableColumns();
+
+        setSizeFull();
+        setCellStyleGenerator(m_associations.createCellStyleGenerator());
+        setSelectable(true);
+        setMultiSelect(true);
+        setImmediate(true);
+        setDragMode(TableDragMode.MULTIROW);
+
+        if (hasEdit) {
+            addListener(new ItemClickListener() {
+                public void itemClick(ItemClickEvent event) {
+                    if (event.isDoubleClick()) {
+                        String itemId = (String) event.getItemId();
+                        RepositoryObject object = getFromId(itemId);
+                        NamedObject namedObject = m_associations.getNamedObject(object);
+                        showEditWindow(namedObject);
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Called by the dependency manager in case a new {@link UIExtensionFactory} is registered.
+     * 
+     * @param ref the service reference of the new extension;
+     * @param factory the extension instance itself.
+     */
+    public final void addExtension(ServiceReference ref, UIExtensionFactory factory) {
+        synchronized (m_extensionFactories) {
+            m_extensionFactories.add(new UIExtensionFactoryHolder(ref, factory));
+        }
+        populate();
+    }
+
+    /**
+     * @see org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event)
+     */
+    public final void handleEvent(org.osgi.service.event.Event event) {
+        final RepositoryObject entity = (RepositoryObject) event.getProperty(RepositoryObject.EVENT_ENTITY);
+        final String topic = event.getTopic();
+
+        synchronized (getApplication()) {
+            if (isSupportedEntity(entity)) {
+                try {
+                    doHandleEvent(topic, (REPO_OBJ) entity, event);
+                }
+                finally {
+                    refreshRenderedCells();
+                }
+            }
+        }
+    }
+
+    /**
+     * @param entity
+     */
+    public void updateEntity(REPO_OBJ entity) {
+        try {
+            update(entity);
+        }
+        finally {
+            refreshRenderedCells();
+        }
+    }
+
+    /**
+     * Called by the dependency manager upon initialization of this component.
+     * 
+     * @param component the component representing this object.
+     */
+    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 + ")")
+            .setCallbacks("addExtension", "removeExtension"));
+    }
+
+    /**
+     * Called to populate this table.
+     */
+    public void populate() {
+        removeAllItems();
+        for (REPO_OBJ object : getAllRepositoryObjects()) {
+            add(object);
+        }
+    }
+
+    /**
+     * Called by the dependency manager in case a {@link UIExtensionFactory} is unregistered.
+     * 
+     * @param ref the service reference of the extension;
+     * @param factory the extension instance itself.
+     */
+    public final void removeExtension(ServiceReference ref, UIExtensionFactory factory) {
+        synchronized (m_extensionFactories) {
+            m_extensionFactories.remove(new UIExtensionFactoryHolder(ref, factory));
+        }
+        populate();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void removeLeftSideAssociation(REPO_OBJ object, RepositoryObject other) {
+        if (doRemoveLeftSideAssociation(object, other)) {
+            m_associations.removeAssociatedItem(object);
+            requestRepaint();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final void removeRightSideAssocation(REPO_OBJ object, RepositoryObject other) {
+        if (doRemoveRightSideAssociation(object, other)) {
+            m_associations.removeAssociatedItem(object);
+            requestRepaint();
+        }
+    }
+
+    /**
+     * Sets the left-side table, that defines the left-hand side of the assocations of the entities.
+     * 
+     * @param leftTable the table to set, can be <code>null</code>.
+     */
+    public final void setLeftTable(Table leftTable) {
+        m_leftTable = leftTable;
+    }
+
+    /**
+     * Sets the right-side table, that defines the right-hand side of the assocations of the entities.
+     * 
+     * @param rightTable the table to set, can be <code>null</code>.
+     */
+    public final void setRightTable(Table rightTable) {
+        m_rightTable = rightTable;
+    }
+
+    /**
+     * Adds a given repository object to this table.
+     * 
+     * @param object the repository object to add, cannot be <code>null</code>.
+     */
+    protected void add(REPO_OBJ object) {
+        Item item = addItem(object.getDefinition());
+        if (item != null) {
+            populateItem(object, item);
+        }
+    }
+
+    /**
+     * Creates the action buttons.
+     * 
+     * @param statefulTarget the target to create the action buttons for, cannot be <code>null</code>.
+     * @return a HorizontalLayout instance with action buttons.
+     */
+    protected HorizontalLayout createActionButtons(REPO_OBJ object) {
+        m_removeLinkButton = createRemoveLinkButton(object);
+        m_deleteButton = createRemoveItemButton(object);
+
+        HorizontalLayout buttons = new HorizontalLayout();
+        if (m_removeLinkButton != null) {
+            buttons.addComponent(m_removeLinkButton);
+        }
+        if (m_deleteButton != null) {
+            buttons.addComponent(m_deleteButton);
+        }
+        return buttons;
+    }
+
+    /**
+     * Factory method to create an embeddable icon.
+     * 
+     * @param name the name of the icon to use (is also used as tooltip text);
+     * @param res the resource denoting the actual icon.
+     * @return an embeddable icon, never <code>null</code>.
+     */
+    protected final Embedded createIcon(String name, Resource res) {
+        Embedded embedded = new Embedded(name, res);
+        embedded.setType(Embedded.TYPE_IMAGE);
+        embedded.setDescription(name);
+        embedded.setHeight(ICON_HEIGHT + "px");
+        embedded.setWidth(ICON_WIDTH + "px");
+        return embedded;
+    }
+
+    /**
+     * Factory method to create an icon resource.
+     * 
+     * @param iconName the base name of the icon to use, it will be appended with '.png'.
+     * @return a {@link Resource} denoting the icon.
+     */
+    protected final Resource createIconResource(String iconName) {
+        return new ThemeResource("icons/" + iconName.toLowerCase() + ".png");
+    }
+
+    /**
+     * Factory method to create a remove-item button.
+     * 
+     * @param object the repository object to create the remove-item button for, cannot be <code>null</code>.
+     * @return a button, can be <code>null</code> if removal of this repository object is not supported.
+     */
+    protected Button createRemoveItemButton(REPO_OBJ object) {
+        return new RemoveItemButton(object, getRepository());
+    }
+
+    /**
+     * Factory method to create a remove-link button.
+     * 
+     * @param object the repository object to create the remove-link button for, cannot be <code>null</code>.
+     * @return a button, can be <code>null</code> if remove-link is not supported.
+     */
+    protected Button createRemoveLinkButton(REPO_OBJ object) {
+        return new RemoveLinkButton<REPO_OBJ>(object, m_leftTable, m_rightTable, this);
+    }
+
+    /**
+     * Defines the table columns for this panel.
+     */
+    protected void defineTableColumns() {
+        addContainerProperty(WORKING_STATE_ICON, Embedded.class, null, "", null, ALIGN_CENTER);
+        addContainerProperty(OBJECT_NAME, String.class, null);
+        addContainerProperty(OBJECT_DESCRIPTION, String.class, null);
+        addContainerProperty(ACTIONS, HorizontalLayout.class, null);
+
+        setColumnWidth(WORKING_STATE_ICON, ICON_WIDTH);
+    }
+
+    /**
+     * @param topic the topic of the event;
+     * @param entity the entity of the event;
+     * @param event the original event.
+     * 
+     * @see org.osgi.service.event.EventHandler#handleEvent(org.osgi.service.event.Event)
+     */
+    protected void doHandleEvent(String topic, REPO_OBJ entity, org.osgi.service.event.Event event) {
+        // Nop...
+    }
+
+    /**
+     * Does the actual removal of the left-hand side associations for a given repository object.
+     * 
+     * @param object the repository object to remove the left-hand side associations;
+     * @param other the (left-hand side) repository object to remove the associations for.
+     * @return <code>true</code> if the associations were removed, <code>false</code> if not.
+     */
+    protected boolean doRemoveLeftSideAssociation(REPO_OBJ object, RepositoryObject other) {
+        return m_leftTable != null;
+    }
+
+    /**
+     * Does the actual removal of the right-hand side associations for a given repository object.
+     * 
+     * @param object the repository object to remove the right-hand side associations;
+     * @param other the (right-hand side) repository object to remove the associations for.
+     * @return <code>true</code> if the associations were removed, <code>false</code> if not.
+     */
+    protected boolean doRemoveRightSideAssociation(REPO_OBJ object, RepositoryObject other) {
+        return m_rightTable != null;
+    }
+
+    /**
+     * Returns the actual repository for objects.
+     * 
+     * @return the actual repository for obtaining the repository objects, cannot be <code>null</code>.
+     */
+    protected abstract REPO getRepository();
+
+    /**
+     * Returns the repository administrator.
+     * 
+     * @return the repository admin, never <code>null</code>.
+     */
+    protected abstract RepositoryAdmin getRepositoryAdmin();
+
+    /**
+     * Determines the working state for the given repository object.
+     * 
+     * @param object the repository object to determine the working state for, cannot be <code>null</code>.
+     * @return the working state for the given repository object, never <code>null</code>.
+     */
+    protected WorkingState getWorkingState(RepositoryObject object) {
+        return getRepositoryAdmin().getWorkingState(object);
+    }
+
+    /**
+     * Helper method to return the working state icon for the given repository object.
+     * 
+     * @param object the repository object to get the icon for, cannot be <code>null</code>.
+     * @return an icon representing the working state of the given repository object, never <code>null</code>.
+     */
+    protected Embedded getWorkingStateIcon(RepositoryObject object) {
+        String name = getWorkingState(object).name();
+        Resource res = createIconResource("resource_workingstate_" + name);
+        return createIcon(name, res);
+    }
+
+    /**
+     * Returns whether the given {@link RepositoryObject} can be handled by this panel.
+     * 
+     * @param entity the entity to test, cannot be <code>null</code>.
+     * @return <code>true</code> if the entity is supported by this panel, <code>false</code> if not.
+     */
+    protected abstract boolean isSupportedEntity(RepositoryObject entity);
+
+    /**
+     * Populates the given table item with information from the given repository object.
+     * 
+     * @param object the repository object to take the information from, cannot be <code>null</code>;
+     * @param item the table item to populate, cannot be <code>null</code>.
+     */
+    protected abstract void populateItem(REPO_OBJ object, Item item);
+
+    /**
+     * Removes a given repository object from this table.
+     * 
+     * @param object the repository object to remove, cannot be <code>null</code>.
+     */
+    protected void remove(REPO_OBJ object) {
+        removeItem(object.getDefinition());
+    }
+
+    /**
+     * Updates a given repository object in this table.
+     * 
+     * @param object the repository object to update, cannot be <code>null</code>.
+     */
+    protected void update(REPO_OBJ object) {
+        Item item = getItem(object.getDefinition());
+        if (item != null) {
+            populateItem(object, item);
+        }
+    }
+
+    /**
+     * Returns all repository objects.
+     * 
+     * @return an {@link Iterable} with all repository objects, never <code>null</code>.
+     */
+    private Iterable<REPO_OBJ> getAllRepositoryObjects() {
+        return getRepository().get();
+    }
+
+    /**
+     * @return a list of current extension factories, properly ordered, never <code>null</code>.
+     */
+    private List<UIExtensionFactory> getExtensionFactories() {
+        List<UIExtensionFactory> extensions;
+        synchronized (m_extensionFactories) {
+            // Sort the list of extension factories...
+            Collections.sort(m_extensionFactories);
+
+            // Walk through the holders and fetch the extension factories one by one...
+            extensions = new ArrayList<UIExtensionFactory>(m_extensionFactories.size());
+            for (UIExtensionFactoryHolder holder : m_extensionFactories) {
+                UIExtensionFactory extensionFactory = holder.getUIExtensionFactory();
+                // Make sure only to use non-GCd factories...
+                if (extensionFactory != null) {
+                    extensions.add(extensionFactory);
+                }
+            }
+        }
+        return extensions;
+    }
+
+    /**
+     * Converts a table-id back to a concrete {@link RepositoryObject}.
+     * 
+     * @param id the identifier of the {@link RepositoryObject}, cannot be <code>null</code>.
+     * @return a {@link RepositoryObject} instance for the given ID, can be <code>null</code> in case no such object is found.
+     */
+    private REPO_OBJ getFromId(String id) {
+        return getRepository().get(id);
+    }
+
+    /**
+     * Shows an edit window for the given named object.
+     * 
+     * @param object the named object to edit;
+     * @param main the main window to use.
+     */
+    private void showEditWindow(NamedObject object) {
+        List<UIExtensionFactory> extensions = getExtensionFactories();
+        new EditWindow(object, extensions).show(getParent().getWindow());
+    }
+}
\ No newline at end of file

Propchange: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/BaseObjectPanel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/DistributionsPanel.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/DistributionsPanel.java?rev=1310280&view=auto
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/DistributionsPanel.java (added)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/DistributionsPanel.java Fri Apr  6 11:28:01 2012
@@ -0,0 +1,115 @@
+/*
+ * 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.component;
+
+import java.util.List;
+
+import org.apache.ace.client.repository.RepositoryAdmin;
+import org.apache.ace.client.repository.RepositoryObject;
+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.DistributionRepository;
+import org.apache.ace.webui.UIExtensionFactory;
+import org.apache.ace.webui.vaadin.Associations;
+
+import com.vaadin.data.Item;
+
+/**
+ *
+ */
+public abstract class DistributionsPanel extends BaseObjectPanel<DistributionObject, DistributionRepository> {
+
+    /**
+     * @param associations
+     */
+    public DistributionsPanel(Associations associations) {
+        super(associations, "Distribution", UIExtensionFactory.EXTENSION_POINT_VALUE_DISTRIBUTION, true /* hasEdit */);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void doHandleEvent(String topic, DistributionObject distribution, org.osgi.service.event.Event event) {
+        if (DistributionObject.TOPIC_ADDED.equals(topic)) {
+            add(distribution);
+        }
+        if (DistributionObject.TOPIC_REMOVED.equals(topic)) {
+            remove(distribution);
+        }
+        if (DistributionObject.TOPIC_CHANGED.equals(topic) || RepositoryAdmin.TOPIC_STATUSCHANGED.equals(topic)) {
+            update(distribution);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean doRemoveLeftSideAssociation(DistributionObject object, RepositoryObject other) {
+        List<Feature2DistributionAssociation> associations = object.getAssociationsWith((FeatureObject) other);
+        for (Feature2DistributionAssociation association : associations) {
+            removeAssocation(association);
+        }
+        return true;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean doRemoveRightSideAssociation(DistributionObject object, RepositoryObject other) {
+        List<Distribution2TargetAssociation> associations = object.getAssociationsWith((TargetObject) other);
+        for (Distribution2TargetAssociation association : associations) {
+            removeAssocation(association);
+        }
+        return true;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean isSupportedEntity(RepositoryObject entity) {
+        return entity instanceof DistributionObject;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void populateItem(DistributionObject distribution, Item item) {
+        item.getItemProperty(WORKING_STATE_ICON).setValue(getWorkingStateIcon(distribution));
+        item.getItemProperty(OBJECT_NAME).setValue(distribution.getName());
+        item.getItemProperty(OBJECT_DESCRIPTION).setValue(distribution.getDescription());
+        item.getItemProperty(ACTIONS).setValue(createActionButtons(distribution));
+    }
+    
+    /**
+     * @param association
+     */
+    protected abstract void removeAssocation(Distribution2TargetAssociation association);
+    
+    /**
+     * @param association
+     */
+    protected abstract void removeAssocation(Feature2DistributionAssociation association);
+}

Propchange: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/DistributionsPanel.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/FeaturesPanel.java
URL: http://svn.apache.org/viewvc/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/FeaturesPanel.java?rev=1310280&view=auto
==============================================================================
--- ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/FeaturesPanel.java (added)
+++ ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/component/FeaturesPanel.java Fri Apr  6 11:28:01 2012
@@ -0,0 +1,116 @@
+/*
+ * 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.component;
+
+import java.util.List;
+
+import org.apache.ace.client.repository.RepositoryAdmin;
+import org.apache.ace.client.repository.RepositoryObject;
+import org.apache.ace.client.repository.object.Artifact2FeatureAssociation;
+import org.apache.ace.client.repository.object.ArtifactObject;
+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.repository.FeatureRepository;
+import org.apache.ace.webui.UIExtensionFactory;
+import org.apache.ace.webui.vaadin.Associations;
+
+import com.vaadin.data.Item;
+
+/**
+ *
+ */
+public abstract class FeaturesPanel extends BaseObjectPanel<FeatureObject, FeatureRepository> {
+
+    /**
+     * @param associations
+     */
+    public FeaturesPanel(Associations associations) {
+        super(associations, "Feature", UIExtensionFactory.EXTENSION_POINT_VALUE_FEATURE, true);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    protected void doHandleEvent(String topic, FeatureObject feature, org.osgi.service.event.Event event) {
+        if (FeatureObject.TOPIC_ADDED.equals(topic)) {
+            add(feature);
+        }
+        if (FeatureObject.TOPIC_REMOVED.equals(topic)) {
+            remove(feature);
+        }
+        if (FeatureObject.TOPIC_CHANGED.equals(topic) || RepositoryAdmin.TOPIC_STATUSCHANGED.equals(topic)) {
+            update(feature);
+        }
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean doRemoveLeftSideAssociation(FeatureObject object, RepositoryObject other) {
+        List<Artifact2FeatureAssociation> associations = object.getAssociationsWith((ArtifactObject) other);
+        for (Artifact2FeatureAssociation association : associations) {
+            removeAssocation(association);
+        }
+        return true;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean doRemoveRightSideAssociation(FeatureObject object, RepositoryObject other) {
+        List<Feature2DistributionAssociation> associations = object.getAssociationsWith((DistributionObject) other);
+        for (Feature2DistributionAssociation association : associations) {
+            removeAssocation(association);
+        }
+        return true;
+    }
+    
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected boolean isSupportedEntity(RepositoryObject entity) {
+        return entity instanceof FeatureObject;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void populateItem(FeatureObject feature, Item item) {
+        item.getItemProperty(WORKING_STATE_ICON).setValue(getWorkingStateIcon(feature));
+        item.getItemProperty(OBJECT_NAME).setValue(feature.getName());
+        item.getItemProperty(OBJECT_DESCRIPTION).setValue(feature.getDescription());
+        item.getItemProperty(ACTIONS).setValue(createActionButtons(feature));
+    }
+    
+    /**
+     * @param association
+     */
+    protected abstract void removeAssocation(Artifact2FeatureAssociation association);
+    
+    /**
+     * @param association
+     */
+    protected abstract void removeAssocation(Feature2DistributionAssociation association);
+}
+



Mime
View raw message