You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ace.apache.org by ma...@apache.org on 2010/11/04 22:28:50 UTC

svn commit: r1031262 [2/24] - in /incubator/ace/trunk/ace-webui-vaadin: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/ace/ src/main/java/org/apache/ace/webui/ src/main/java/org/apache/ace/webui/v...

Added: incubator/ace/trunk/ace-webui-vaadin/osgi.bnd
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/osgi.bnd?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/osgi.bnd (added)
+++ incubator/ace/trunk/ace-webui-vaadin/osgi.bnd Thu Nov  4 21:28:26 2010
@@ -0,0 +1,11 @@
+Bundle-Version>: \
+  ${pom.version}
+
+Bundle-SymbolicName: \
+  ${bundle.symbolicName}
+
+Bundle-Name: Apache ACE - Client Web UI (Vaadin)
+
+Bundle-Activator: org.apache.ace.webui.vaadin.Activator
+
+Import-Package: *

Added: incubator/ace/trunk/ace-webui-vaadin/pom.xml
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/pom.xml?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/pom.xml (added)
+++ incubator/ace/trunk/ace-webui-vaadin/pom.xml Thu Nov  4 21:28:26 2010
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.ace</groupId>
+        <artifactId>ace-pom</artifactId>
+        <version>0.8.0-SNAPSHOT</version>
+        <relativePath>../pom/</relativePath>
+    </parent>
+
+    <groupId>org.apache.ace</groupId>
+    <artifactId>ace-webui-vaadin</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache ACE - Web UI Vaadin</name>
+
+    <properties>
+        <bundle.symbolicName>${namespace}.webui.vaadin</bundle.symbolicName>
+        <bundle.namespace>${namespace}</bundle.namespace>
+    </properties>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <version>2.0.0</version>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.dependencymanager</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ace-client-repository-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>ace-httplistener</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.vaadin</groupId>
+            <artifactId>vaadin</artifactId>
+            <version>6.4.6</version>
+        </dependency>
+    </dependencies>
+
+    <repositories>
+        <repository>
+            <id>ace-repository</id>
+            <url>http://svn.apache.org/repos/asf/incubator/ace/repo</url>
+        </repository>
+    </repositories>
+</project>
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/Activator.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/Activator.java?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/Activator.java (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/Activator.java Thu Nov  4 21:28:26 2010
@@ -0,0 +1,35 @@
+package org.apache.ace.webui.vaadin;
+
+import java.util.Properties;
+
+import javax.servlet.http.HttpServlet;
+
+import org.apache.ace.http.listener.constants.HttpConstants;
+import org.apache.felix.dm.DependencyActivatorBase;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.http.HttpService;
+
+public class Activator extends DependencyActivatorBase {
+    @Override
+    public void init(BundleContext context, DependencyManager manager) throws Exception {
+        manager.add(createComponent()
+            .setImplementation(VaadinResourceHandler.class)
+            .add(createServiceDependency()
+                .setService(HttpService.class)
+                .setRequired(true)
+            )
+        );
+        // register the main application for the ACE UI client
+        Properties props = new Properties();
+        props.put(HttpConstants.ENDPOINT, "/ace");
+        manager.add(createComponent()
+            .setInterface(HttpServlet.class.getName(), props)
+            .setImplementation(VaadinServlet.class)
+        );
+    }
+    
+    @Override
+    public void destroy(BundleContext context, DependencyManager manager) throws Exception {
+    }
+}

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinClient.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinClient.java?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinClient.java (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinClient.java Thu Nov  4 21:28:26 2010
@@ -0,0 +1,755 @@
+package org.apache.ace.webui.vaadin;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ace.client.repository.RepositoryAdmin;
+import org.apache.ace.client.repository.RepositoryAdminLoginContext;
+import org.apache.ace.client.repository.RepositoryObject;
+import org.apache.ace.client.repository.SessionFactory;
+import org.apache.ace.client.repository.object.ArtifactObject;
+import org.apache.ace.client.repository.object.GatewayObject;
+import org.apache.ace.client.repository.object.Group2LicenseAssociation;
+import org.apache.ace.client.repository.object.GroupObject;
+import org.apache.ace.client.repository.object.LicenseObject;
+import org.apache.ace.client.repository.repository.Artifact2GroupAssociationRepository;
+import org.apache.ace.client.repository.repository.ArtifactRepository;
+import org.apache.ace.client.repository.repository.GatewayRepository;
+import org.apache.ace.client.repository.repository.Group2LicenseAssociationRepository;
+import org.apache.ace.client.repository.repository.GroupRepository;
+import org.apache.ace.client.repository.repository.License2GatewayAssociationRepository;
+import org.apache.ace.client.repository.repository.LicenseRepository;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+import com.vaadin.data.Item;
+import com.vaadin.data.Property.ValueChangeEvent;
+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;
+import com.vaadin.event.dd.TargetDetails;
+import com.vaadin.event.dd.acceptcriteria.AcceptAll;
+import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
+import com.vaadin.terminal.Sizeable;
+import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Table;
+import com.vaadin.ui.Table.CellStyleGenerator;
+import com.vaadin.ui.Table.TableDragMode;
+import com.vaadin.ui.Table.TableTransferable;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+/*
+
+TODO:
+ - Add an editor that appears on double clicking on an item in a table (partially done)
+ - Enable drag and drop to create associations (partially done)
+ - Add buttons to remove associations (think about how we can better visualize this)
+ - Add buttons to create new items in all of the tables (partially done)
+ - Add drag and drop to the artifacts column (partially done)
+ - Create a special editor for dealing with new artifact types
+ */
+public class VaadinClient extends com.vaadin.Application {
+    private static final String OBJECT_NAME = "name";
+	private static final String OBJECT_DESCRIPTION = "description";
+    private static final long serialVersionUID = 1L;
+    private static long SESSION_ID = 12345;
+    private static String gatewayRepo = "gateway";
+    private static String shopRepo = "shop";
+    private static String deployRepo = "deployment";
+    private static String customerName = "apache";
+    private static String hostName = "http://localhost:8080";
+    private static String endpoint = "/repository";
+    private static String obr = "http://localhost:8080/obr/";
+
+    private volatile DependencyManager m_manager;
+    private volatile BundleContext m_context;
+    private volatile SessionFactory m_sessionFactory;
+    private volatile UserAdmin m_userAdmin;
+    private volatile ArtifactRepository m_artifactRepository;
+    private volatile GroupRepository m_featureRepository;
+    private volatile LicenseRepository m_distributionRepository;
+    private volatile GatewayRepository m_targetRepository;
+    private volatile Artifact2GroupAssociationRepository m_artifact2GroupAssciationRepository;
+    private volatile Group2LicenseAssociationRepository m_group2LicenseAssociationRepository;
+    private volatile License2GatewayAssociationRepository m_license2GatewayAssociationRepository;
+    private volatile RepositoryAdmin m_admin;
+    private volatile LogService m_log;
+    private String m_sessionID;
+    private volatile List<LicenseObject> m_distributions;
+    private Table m_artifactsPanel;
+    private Table m_featuresPanel;
+	private Table m_distributionsPanel;
+    private Table m_targetsPanel;
+    private List<ArtifactObject> m_artifacts;
+    private List<GroupObject> m_features;
+    private List<GatewayObject> m_targets;
+    private List<RepositoryObject> m_associatedItems = new ArrayList<RepositoryObject>();
+    private List<RepositoryObject> m_relatedItems = new ArrayList<RepositoryObject>();
+    
+    private Table m_activeTable;
+    private Set<?> m_activeSelection;
+    public SelectionListener m_activeSelectionListener;
+
+    // basic session ID generator
+	private static long generateSessionID() {
+        return SESSION_ID++;
+    }
+    
+    public void setupDependencies(Component component) {
+        System.out.println("SETUP " + this);
+        m_sessionID = "" + generateSessionID();
+        m_sessionFactory.createSession(m_sessionID);
+        addDependency(component, RepositoryAdmin.class);
+        addDependency(component, LicenseRepository.class);
+        addDependency(component, ArtifactRepository.class);
+        addDependency(component, GroupRepository.class);
+        addDependency(component, GatewayRepository.class);
+        addDependency(component, Artifact2GroupAssociationRepository.class);
+        addDependency(component, Group2LicenseAssociationRepository.class);
+        addDependency(component, License2GatewayAssociationRepository.class);
+    }
+    
+    private void addDependency(Component component, Class service) {
+        component.add(m_manager.createServiceDependency()
+            .setService(service, "(" + SessionFactory.SERVICE_SID + "=" + m_sessionID + ")")
+            .setRequired(true)
+            .setInstanceBound(true)
+        );
+    }
+    
+    public void start() {
+        System.out.println("START " + this);
+    }
+    
+    public void stop() {
+        System.out.println("STOP " + this);
+    }
+    
+    public void destroyDependencies() {
+        System.out.println("DESTROY " + this);
+        m_sessionFactory.destroySession(m_sessionID);
+    }
+    
+    
+    public void init() {
+        System.out.println("INIT " + this);
+        
+        try {
+            User user = m_userAdmin.getUser("username", "d");
+            RepositoryAdminLoginContext context = m_admin.createLoginContext(user);
+            
+            context.addShopRepository(new URL(hostName + endpoint), customerName, shopRepo, true)
+                .setObrBase(new URL(obr))
+                .addGatewayRepository(new URL(hostName + endpoint), customerName, gatewayRepo, true)
+                .addDeploymentRepository(new URL(hostName + endpoint), customerName, deployRepo, true);
+            m_admin.login(context);
+            m_admin.checkout();
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+        }
+        
+        setTheme("ace");
+        final Window main = new Window("Apache ACE - User Interface - " + this);
+        setMainWindow(main);
+        main.getContent().setSizeFull();
+        
+        final GridLayout grid = new GridLayout(4, 3);
+        grid.setSpacing(true);
+
+        grid.setWidth(100, Sizeable.UNITS_PERCENTAGE);
+        grid.setHeight(100, Sizeable.UNITS_PERCENTAGE);
+
+        // toolbar
+        GridLayout toolbar = new GridLayout(3,1);
+        toolbar.setSpacing(true);
+        
+        Button retrieveButton = new Button("Retrieve");
+        retrieveButton.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                try {
+                    m_admin.checkout();
+                    System.out.println("checkout");
+                    updateTableData();
+                }
+                catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        });
+        toolbar.addComponent(retrieveButton, 0, 0);
+        
+        Button storeButton = new Button("Store");
+        storeButton.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                try {
+                    m_admin.commit();
+                    System.out.println("commit");
+                    updateTableData();
+                }
+                catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        });
+        toolbar.addComponent(storeButton, 1, 0);
+        Button revertButton = new Button("Revert");
+        revertButton.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                try {
+                    m_admin.revert();
+                    System.out.println("revert");
+                    updateTableData();
+                }
+                catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        });
+        toolbar.addComponent(revertButton, 2, 0);
+        
+        grid.addComponent(toolbar, 0, 0, 3, 0);
+        
+        m_distributionsPanel = new Table("Distributions");
+        m_distributionsPanel.addContainerProperty(OBJECT_NAME, String.class, null);
+        m_distributionsPanel.addContainerProperty(OBJECT_DESCRIPTION, String.class, null);
+        m_distributionsPanel.addContainerProperty("button", Button.class, null);
+        m_distributionsPanel.setSizeFull();
+        m_distributionsPanel.setCellStyleGenerator(new CellStyleGeneratorImplementation() {
+            @Override
+            public boolean equals(Object itemId, RepositoryObject object) {
+                return ((object instanceof LicenseObject) && ((LicenseObject) object).getName().equals(itemId));
+            }
+        });
+        m_distributionsPanel.setSelectable(true);
+        m_distributionsPanel.setMultiSelect(true);
+        m_distributionsPanel.setImmediate(true);
+        m_distributionsPanel.setDropHandler(new DropHandler() {
+
+            public void drop(DragAndDropEvent event) {
+                Transferable transferable = event.getTransferable();
+                TargetDetails targetDetails = event.getTargetDetails();
+                System.out.println("F: " + transferable);
+                if (transferable instanceof TableTransferable) {
+                    TableTransferable tt = (TableTransferable) transferable;
+                    Object fromItemId = tt.getItemId();
+                    System.out.println("FF: " + fromItemId);
+                    System.out.println("T: " + targetDetails.getClass().getName());
+                    if (targetDetails instanceof AbstractSelectTargetDetails) {
+                        AbstractSelectTargetDetails ttd = (AbstractSelectTargetDetails) targetDetails;
+                        Object toItemId = ttd.getItemIdOver();
+                        System.out.println("TT: " + toItemId);
+                        m_group2LicenseAssociationRepository.create(getFeature((String) fromItemId), getDistribution((String) toItemId));
+                        updateTableData();
+                    }
+                }
+            }
+
+            public AcceptCriterion getAcceptCriterion() {
+                return AcceptAll.get();
+            }});
+        
+        
+        grid.setRowExpandRatio(2, 1.0f);
+        
+        grid.addComponent(m_distributionsPanel, 2, 2);
+        grid.addComponent(new Button("Add distribution..."), 2, 1);
+        
+        m_artifactsPanel = new Table("Artifacts");
+        m_artifactsPanel.addContainerProperty(OBJECT_NAME, String.class, null);
+        m_artifactsPanel.addContainerProperty(OBJECT_DESCRIPTION, String.class, null);
+        m_artifactsPanel.setSizeFull();
+        m_artifactsPanel.setCellStyleGenerator(new CellStyleGeneratorImplementation() {
+            @Override
+            public boolean equals(Object itemId, RepositoryObject object) {
+                return ((object instanceof ArtifactObject) && ((ArtifactObject) object).getName().equals(itemId));
+            }
+        });
+        m_artifactsPanel.setSelectable(true);
+        m_artifactsPanel.setMultiSelect(true);
+        m_artifactsPanel.setImmediate(true);
+        grid.addComponent(m_artifactsPanel, 0, 2);
+        grid.addComponent(new Button("Add artifact..."), 0, 1);
+        
+        Button addFeature = new Button("Add Feature...");
+        addFeature.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                final Window featureWindow;
+                featureWindow = new Window();
+                featureWindow.setModal(true);
+                featureWindow.setCaption("Add Feature");
+                featureWindow.setWidth("15em");
+                
+             // Configure the windws layout; by default a VerticalLayout
+                VerticalLayout layout = (VerticalLayout) featureWindow.getContent();
+                layout.setMargin(true);
+                layout.setSpacing(true);
+
+                final TextField name = new TextField("name");
+                final TextField description = new TextField("description");
+
+                layout.addComponent(name);
+                layout.addComponent(description);
+                
+                Button close = new Button("Close", new Button.ClickListener() {
+                    // inline click-listener
+                    public void buttonClick(ClickEvent event) {
+                        // close the window by removing it from the parent window
+                        (featureWindow.getParent()).removeWindow(featureWindow);
+                        // create the feature
+                        createFeature((String) name.getValue(), (String) description.getValue());
+                        updateTableData();
+                    }
+                });
+                // 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, "right");
+                
+                if (featureWindow.getParent() != null) {
+                    // window is already showing
+                    main.getWindow().showNotification(
+                            "Window is already open");
+                } else {
+                    // Open the subwindow by adding it to the parent
+                    // window
+                    main.getWindow().addWindow(featureWindow);
+                }
+                name.focus();
+            }
+        });
+        
+        
+        
+        grid.addComponent(addFeature, 1, 1);
+        
+        m_featuresPanel = new Table("Features");
+        m_featuresPanel.addContainerProperty(OBJECT_NAME, String.class, null);
+        m_featuresPanel.addContainerProperty(OBJECT_DESCRIPTION, String.class, null);
+        m_featuresPanel.setSizeFull();
+        m_featuresPanel.setCellStyleGenerator(new CellStyleGeneratorImplementation() {
+            @Override
+            public boolean equals(Object itemId, RepositoryObject object) {
+                return ((object instanceof GroupObject) && ((GroupObject) object).getName().equals(itemId));
+            }
+        });
+        m_featuresPanel.setSelectable(true);
+        m_featuresPanel.setMultiSelect(true);
+        m_featuresPanel.setImmediate(true);
+        m_featuresPanel.setDragMode(TableDragMode.ROW);
+        m_featuresPanel.addListener(new ItemClickListener() {
+            public void itemClick(ItemClickEvent event) {
+                if (event.isDoubleClick()) {
+                    String itemId = (String) event.getItemId();
+                    final GroupObject feature = getFeature(itemId);
+                    final Window featureWindow = new Window();
+                    featureWindow.setModal(true);
+                    featureWindow.setCaption("Edit Feature");
+                    featureWindow.setWidth("15em");
+                    
+                 // Configure the windws layout; by default a VerticalLayout
+                    VerticalLayout layout = (VerticalLayout) featureWindow.getContent();
+                    layout.setMargin(true);
+                    layout.setSpacing(true);
+
+                    final TextField name = new TextField("name");
+                    final TextField description = new TextField("description");
+
+                    name.setValue(feature.getName());
+                    description.setValue(feature.getDescription());
+                    
+                    layout.addComponent(name);
+                    layout.addComponent(description);
+                    
+                    Button close = new Button("Close", new Button.ClickListener() {
+                        // inline click-listener
+                        public void buttonClick(ClickEvent event) {
+                            // close the window by removing it from the parent window
+                            (featureWindow.getParent()).removeWindow(featureWindow);
+                            // create the feature
+                            feature.setDescription((String) description.getValue());
+                            updateTableData();
+                        }
+                    });
+                    // 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, "right");
+                    
+                    if (featureWindow.getParent() != null) {
+                        // window is already showing
+                        main.getWindow().showNotification(
+                                "Window is already open");
+                    } else {
+                        // Open the subwindow by adding it to the parent
+                        // window
+                        main.getWindow().addWindow(featureWindow);
+                    }
+                    name.setReadOnly(true);
+                    description.focus();
+
+                }
+            }
+        });
+
+        
+        grid.addComponent(m_featuresPanel, 1, 2);
+        
+        m_targetsPanel = new Table("Targets");
+        m_targetsPanel.addContainerProperty(OBJECT_NAME, String.class, null);
+        m_targetsPanel.addContainerProperty(OBJECT_DESCRIPTION, String.class, null);
+        m_targetsPanel.setSizeFull();
+        m_targetsPanel.setCellStyleGenerator(new CellStyleGeneratorImplementation() {
+            @Override
+            public boolean equals(Object itemId, RepositoryObject object) {
+                return ((object instanceof GatewayObject) && ((GatewayObject) object).getID().equals(itemId));
+            }
+        });
+        m_targetsPanel.setSelectable(true);
+        m_targetsPanel.setMultiSelect(true);
+        m_targetsPanel.setImmediate(true);
+        grid.addComponent(m_targetsPanel, 3, 2);
+        grid.addComponent(new Button("Add target..."), 3, 1);
+        
+        m_artifactsPanel.addListener(new SelectionListener(m_artifactsPanel, new Class[] {}, new Class[] { GroupObject.class, LicenseObject.class, GatewayObject.class }, new Table[] { m_featuresPanel, m_distributionsPanel, m_targetsPanel }) {
+            @Override
+            public RepositoryObject lookup(Object value) {
+                for (ArtifactObject object : m_artifactRepository.get()) {
+                    if (object.getName().equals(value)) {
+                        System.out.println("Found: " + object.getName());
+                        return object;
+                    }
+                }
+                return null;
+            }
+        });
+        m_featuresPanel.addListener(new SelectionListener(m_featuresPanel, new Class[] { ArtifactObject.class }, new Class[] { LicenseObject.class, GatewayObject.class }, new Table[] { m_artifactsPanel, m_distributionsPanel, m_targetsPanel }) {
+            @Override
+            public RepositoryObject lookup(Object value) {
+                for (GroupObject object : m_featureRepository.get()) {
+                    if (object.getName().equals(value)) {
+                        System.out.println("Found: " + object.getName());
+                        return object;
+                    }
+                }
+                return null;
+            }
+        });
+        m_distributionsPanel.addListener(new SelectionListener(m_distributionsPanel, new Class[] { GroupObject.class, ArtifactObject.class }, new Class[] { GatewayObject.class }, new Table[] { m_artifactsPanel, m_featuresPanel, m_targetsPanel }) {
+            @Override
+            public RepositoryObject lookup(Object value) {
+                for (LicenseObject object : m_distributionRepository.get()) {
+                    if (object.getName().equals(value)) {
+                        System.out.println("Found: " + object.getName());
+                        return object;
+                    }
+                }
+                return null;
+            }
+        });
+        m_targetsPanel.addListener(new SelectionListener(m_targetsPanel, new Class[] { LicenseObject.class, GroupObject.class, ArtifactObject.class}, new Class[] {}, new Table[] { m_artifactsPanel, m_featuresPanel, m_distributionsPanel }) {
+            @Override
+            public RepositoryObject lookup(Object value) {
+                for (GatewayObject object : m_targetRepository.get()) {
+                    if (object.getID().equals(value)) {
+                        System.out.println("Found: " + object.getID());
+                        return object;
+                    }
+                }
+                return null;
+            }
+        });
+
+        
+        updateTableData();
+        
+        main.addComponent(grid);
+    }
+    
+    private void createFeature(String name, String description) {
+        Map<String, String> attributes = new HashMap<String, String>();
+        attributes.put(GroupObject.KEY_NAME, name);
+        attributes.put(GroupObject.KEY_DESCRIPTION, description);
+        Map<String, String> tags = new HashMap<String, String>();
+        m_featureRepository.create(attributes, tags);
+    }
+    private GroupObject getFeature(String name) {
+        try {
+            List<GroupObject> list = m_featureRepository.get(m_context.createFilter("(" + GroupObject.KEY_NAME + "=" + name + ")"));
+            if (list.size() == 1) {
+                return list.get(0);
+            }
+        }
+        catch (InvalidSyntaxException e) {
+        }
+        return null;
+    }
+    
+    private void deleteFeature(String name) {
+        GroupObject feature = getFeature(name);
+        if (feature != null) {
+            m_featureRepository.remove(feature);
+            // TODO cleanup links?
+        }
+    }
+    
+    private LicenseObject getDistribution(String name) {
+        try {
+            List<LicenseObject> list = m_distributionRepository.get(m_context.createFilter("(" + LicenseObject.KEY_NAME + "=" + name + ")"));
+            if (list.size() == 1) {
+                return list.get(0);
+            }
+        }
+        catch (InvalidSyntaxException e) {
+        }
+        return null;
+    }
+    
+//    private GroupObject editFeature(String name, String description) {
+//        try {
+//            List<GroupObject> list = m_featureRepository.get(m_context.createFilter("(" + GroupObject.KEY_NAME + "=" + name + ")"));
+//            if (list.size() == 1) {
+//                return list.get(0);
+//            }
+//            Map<String, String> attributes = new HashMap<String, String>();
+////            attributes.put(GroupObject.KEY_NAME, name);
+//            attributes.put(GroupObject.KEY_DESCRIPTION, description);
+//            Map<String, String> tags = new HashMap<String, String>();
+////            m_featureRepository.create(attributes, tags);
+//        }
+//        catch (InvalidSyntaxException e) {
+//            // TODO Auto-generated catch block
+//            e.printStackTrace();
+//        }
+//    }
+    private void createDistribution(String name, String description) {
+        Map<String, String> attributes = new HashMap<String, String>();
+        attributes.put(LicenseObject.KEY_NAME, name);
+        attributes.put(LicenseObject.KEY_DESCRIPTION, description);
+        Map<String, String> tags = new HashMap<String, String>();
+        m_distributionRepository.create(attributes, tags);
+    }
+    
+    /**
+     * Helper method to find all related {@link RepositoryObject}s in a given 'direction'
+     */
+    private <FROM extends RepositoryObject, TO extends RepositoryObject> List<TO> getRelated(FROM from, Class<TO> toClass) {
+        return from.getAssociations(toClass);
+    }
+    
+    /**
+     * Helper method to find all related {@link RepositoryObject}s in a given 'direction', starting with a list of objects
+     */
+    private <FROM extends RepositoryObject, TO extends RepositoryObject> List<TO> getRelated(List<FROM> from, Class<TO> toClass) {
+        List<TO> result = new ArrayList<TO>();
+        for (RepositoryObject o : from) {
+            result.addAll(getRelated(o, toClass));
+        }
+        return result;
+    }
+
+
+    
+    private void updateTableData() {
+        m_artifacts = m_artifactRepository.get();
+        m_artifactsPanel.removeAllItems();
+        for (ArtifactObject artifact : m_artifacts) {
+            Item item = m_artifactsPanel.addItem(artifact.getName());
+            item.getItemProperty(OBJECT_NAME).setValue(artifact.getName());
+            item.getItemProperty(OBJECT_DESCRIPTION).setValue(artifact.getDescription());
+        }
+        m_features = m_featureRepository.get();
+        m_featuresPanel.removeAllItems();
+        for (GroupObject group : m_features) {
+            Item licenseItem = m_featuresPanel.addItem(group.getName());
+            licenseItem.getItemProperty(OBJECT_NAME).setValue(group.getName());
+            licenseItem.getItemProperty(OBJECT_DESCRIPTION).setValue(group.getDescription());
+        }
+        m_distributions = m_distributionRepository.get();
+        m_distributionsPanel.removeAllItems();
+        for (LicenseObject license : m_distributions) {
+            Item licenseItem = m_distributionsPanel.addItem(license.getName());
+            licenseItem.getItemProperty(OBJECT_NAME).setValue(license.getName());
+            licenseItem.getItemProperty(OBJECT_DESCRIPTION).setValue(license.getDescription());
+            Button removeLinkButton = new Button("-");
+            final LicenseObject distribution = license;
+            removeLinkButton.addListener(new Button.ClickListener() {
+                public void buttonClick(ClickEvent event) {
+                    System.out.println("Removing link to " + distribution.getName());
+                    if (m_activeTable.equals(m_featuresPanel)) {
+                        Set<?> selection = m_activeSelection;
+                        if (selection != null) {
+                            for (Object item : selection) {
+                                RepositoryObject object = m_activeSelectionListener.lookup(item);
+                                List<Group2LicenseAssociation> associations = distribution.getAssociationsWith((GroupObject) object);
+                                for (Group2LicenseAssociation g2l : associations) {
+                                    System.out.println("> " + g2l.getLeft() + " <-> " + g2l.getRight());
+                                    m_group2LicenseAssociationRepository.remove(g2l);
+                                }
+                                m_associatedItems.remove(object);
+                            }
+//                            updateTableData();
+                        }
+                    }
+                    if (m_activeTable.equals(m_targetsPanel)) {
+                        
+                    }
+                }
+            });
+            licenseItem.getItemProperty("button").setValue(removeLinkButton);
+        }
+        m_targets = m_targetRepository.get();
+        m_targetsPanel.removeAllItems();
+        for (GatewayObject license : m_targets) {
+            Item licenseItem = m_targetsPanel.addItem(license.getID());
+            licenseItem.getItemProperty(OBJECT_NAME).setValue(license.getID());
+            licenseItem.getItemProperty(OBJECT_DESCRIPTION).setValue("?");
+        }
+    }
+    
+    @Override
+    public void close() {
+        super.close();
+        // when the session times out
+        // TODO: clean up the ace client session?
+    }
+
+    public abstract class SelectionListener implements Table.ValueChangeListener {
+        private final Table m_table;
+        private final Table[] m_tablesToRefresh;
+        private final Class[] m_left;
+        private final Class[] m_right;
+        public SelectionListener(Table table, Class[] left, Class[] right, Table[] tablesToRefresh) {
+            m_table = table;
+            m_left = left;
+            m_right = right;
+            m_tablesToRefresh = tablesToRefresh;
+        }
+        
+        public void valueChange(ValueChangeEvent event) {
+            m_activeSelectionListener = this;
+            
+            // set the active table
+            m_activeTable = m_table;
+            
+            // in multiselect mode, a Set of itemIds is returned,
+            // in singleselect mode the itemId is returned directly
+            Set<?> value = (Set<?>) event.getProperty().getValue();
+            if (null == value || value.size() == 0) {
+//                    selected.setValue("No selection");
+            } else {
+//                    selected.setValue("Selected: " + table.getValue());
+            }
+
+            // remember the active selection too
+            m_activeSelection = value;
+
+            if (value == null) {
+                System.out.println("no selection");
+            }
+            else {
+                System.out.println("selection:");
+                
+                m_associatedItems.clear();
+                m_relatedItems.clear();
+                for (Object val : value) {
+                    System.out.println(" - " + m_table.getItem(val).getItemProperty(OBJECT_NAME) + " " + val);
+                    RepositoryObject lo = lookup(val);
+                    
+                    List related = null;
+                    for (int i = 0; i < m_left.length; i++) {
+                        if (i == 0) {
+                            related = getRelated(lo, m_left[i]);
+                            System.out.println("left associated:");
+                            for (Object o : related) {
+                                System.out.println(" -> " + o);
+                            }
+                            m_associatedItems.addAll(related);
+                        }
+                        else {
+                            related = getRelated(related, m_left[i]);
+                            System.out.println("left related:");
+                            for (Object o : related) {
+                                System.out.println(" -> " + o);
+                            }
+                            m_relatedItems.addAll(related);
+                        }
+                    }
+                    for (int i = 0; i < m_right.length; i++) {
+                        if (i == 0) {
+                            related = getRelated(lo, m_right[i]);
+                            System.out.println("right associated:");
+                            for (Object o : related) {
+                                System.out.println(" -> " + o);
+                            }
+                            m_associatedItems.addAll(related);
+                        }
+                        else {
+                            related = getRelated(related, m_right[i]);
+                            System.out.println("right related:");
+                            for (Object o : related) {
+                                System.out.println(" -> " + o);
+                            }
+                            m_relatedItems.addAll(related);
+                        }
+                    }
+                    
+                    for (Table t : m_tablesToRefresh) {
+                        System.out.println("refreshing " + t);
+                        t.setValue(null);
+                        t.requestRepaint();
+                    }
+                    // when switching columns, we need to repaint, but it messes up the
+                    // cursor position
+//                    m_table.requestRepaint();
+                }
+            }
+        }
+        public abstract RepositoryObject lookup(Object value);
+    }
+
+    /** Highlights associated and related items in other columns. */
+    private abstract class CellStyleGeneratorImplementation implements CellStyleGenerator {
+        public String getStyle(Object itemId, Object propertyId) {
+            if (propertyId == null) {
+                // no propertyId, styling row
+                for (RepositoryObject o : m_associatedItems) {
+                    System.out.println("cellrenderer probing: " + o);
+                    if (equals(itemId, o)) {
+                        System.out.println(" -> associated");
+                        return "associated";
+                    }
+                }
+                for (RepositoryObject o : m_relatedItems) {
+                    if (equals(itemId, o)) {
+                        System.out.println(" -> related");
+                        return "related";
+                    }
+                }
+                System.out.println("cellrenderer: unrelated");
+            }
+            return null;
+        }
+        public abstract boolean equals(Object itemId, RepositoryObject object);
+    }
+}
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinResourceHandler.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinResourceHandler.java?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinResourceHandler.java (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinResourceHandler.java Thu Nov  4 21:28:26 2010
@@ -0,0 +1,47 @@
+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.service.http.HttpContext;
+import org.osgi.service.http.HttpService;
+import org.osgi.service.http.NamespaceException;
+
+public class VaadinResourceHandler {
+    private volatile HttpService m_http;
+    private HttpContext m_context;
+    
+    public void start() {
+        m_context = m_http.createDefaultHttpContext();
+        try {
+            m_http.registerResources("/VAADIN", "/VAADIN", new HttpContext() {
+                public String getMimeType(String name) {
+                    return m_context.getMimeType(name);
+                }
+
+                public URL getResource(String name) {
+                    URL resource = null;
+                    String prefix = "/VAADIN/";
+                    if (name.startsWith(prefix)) {
+                        resource = getClass().getResource(name);
+                        if (resource == null) {
+                            // try to find the resource in the Vaadin bundle instead
+                            resource = com.vaadin.Application.class.getResource(name);
+                        }
+                    }
+                    return resource;
+                }
+
+                public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
+                    return m_context.handleSecurity(request, response);
+                }});
+        }
+        catch (NamespaceException e) {
+            e.printStackTrace();
+        }
+    }
+}

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinServlet.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinServlet.java?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinServlet.java (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/VaadinServlet.java Thu Nov  4 21:28:26 2010
@@ -0,0 +1,44 @@
+package org.apache.ace.webui.vaadin;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.ace.client.repository.SessionFactory;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.UserAdmin;
+
+import com.vaadin.Application;
+import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
+
+public class VaadinServlet extends AbstractApplicationServlet {
+	private static final long serialVersionUID = 1L;
+	private volatile DependencyManager m_manager;
+    
+    @Override
+    protected Class<? extends Application> getApplicationClass() {
+        return VaadinClient.class;
+    }
+
+    @Override
+    protected Application getNewApplication(HttpServletRequest request)	throws ServletException {
+        Application application = new VaadinClient();
+        m_manager.add(m_manager.createComponent()
+            .setImplementation(application)
+            .setCallbacks("setupDependencies", "start", "stop", "destroyDependencies")
+            .add(m_manager.createServiceDependency()
+                .setService(SessionFactory.class)
+                .setRequired(true)
+            )
+            .add(m_manager.createServiceDependency()
+                .setService(UserAdmin.class)
+                .setRequired(true)
+            )
+            .add(m_manager.createServiceDependency()
+                .setService(LogService.class)
+                .setRequired(false)
+            )
+        );
+        return application;
+    }
+}

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/bazaar/BazaarManager.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/bazaar/BazaarManager.java?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/bazaar/BazaarManager.java (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/bazaar/BazaarManager.java Thu Nov  4 21:28:26 2010
@@ -0,0 +1,307 @@
+package org.apache.ace.webui.vaadin.bazaar;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+
+import org.apache.ace.client.repository.RepositoryAdmin;
+import org.apache.ace.client.repository.RepositoryAdminLoginContext;
+import org.apache.ace.client.repository.SessionFactory;
+import org.apache.ace.client.repository.object.GatewayObject;
+import org.apache.ace.client.repository.object.LicenseObject;
+import org.apache.ace.client.repository.repository.LicenseRepository;
+import org.apache.felix.dm.Component;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.User;
+import org.osgi.service.useradmin.UserAdmin;
+
+import com.vaadin.data.Property;
+import com.vaadin.data.Property.ValueChangeEvent;
+import com.vaadin.terminal.ExternalResource;
+import com.vaadin.terminal.Sizeable;
+import com.vaadin.terminal.ThemeResource;
+import com.vaadin.ui.Alignment;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.CheckBox;
+import com.vaadin.ui.Embedded;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.Panel;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.Button.ClickEvent;
+
+public class BazaarManager extends com.vaadin.Application {
+	private static final long serialVersionUID = 1L;
+
+    private volatile DependencyManager m_manager;
+    private volatile SessionFactory m_sessionFactory;
+    private volatile UserAdmin m_userAdmin;
+    private volatile LicenseRepository m_distributionRepository;
+    private volatile RepositoryAdmin m_admin;
+    private volatile LogService m_log;
+    private String m_sessionID;
+    
+    private static long SESSION_ID = 1;
+
+    private static String gatewayRepo = "gateway";
+    private static String shopRepo = "shop";
+    private static String deployRepo = "deployment";
+    private static String customerName = "apache";
+    private static String hostName = "http://localhost:8080";
+    private static String endpoint = "/repository";
+    private static String obr = "http://localhost:8080/obr/";
+    private volatile List<LicenseObject> m_distributions;
+
+	private Panel m_distributionsPanel;
+    
+	private static long generateSessionID() {
+        return SESSION_ID++;
+    }
+    
+    public void setupDependencies(Component component) {
+        System.out.println("SETUP " + this);
+        m_sessionID = "" + generateSessionID();
+        m_sessionFactory.createSession(m_sessionID);
+        component.add(m_manager.createServiceDependency()
+            .setService(RepositoryAdmin.class, "(" + SessionFactory.SERVICE_SID + "=" + m_sessionID + ")")
+            .setRequired(true)
+            .setInstanceBound(true)
+            );
+        component.add(m_manager.createServiceDependency()
+            .setService(LicenseRepository.class, "(" + SessionFactory.SERVICE_SID + "=" + m_sessionID + ")")
+            .setRequired(true)
+            .setInstanceBound(true)
+            );
+    }
+    
+    public void start() {
+        System.out.println("START " + this);
+    }
+    
+    public void stop() {
+        System.out.println("STOP " + this);
+    }
+    
+    public void destroyDependencies() {
+        System.out.println("DESTROY " + this);
+        m_sessionFactory.destroySession(m_sessionID);
+    }
+    
+    
+    public void init() {
+        System.out.println("INIT " + this);
+        
+        try {
+            User user = m_userAdmin.getUser("username", "d");
+            RepositoryAdminLoginContext context = m_admin.createLoginContext(user);
+            
+            context.addShopRepository(new URL(hostName + endpoint), customerName, shopRepo, true)
+            .setObrBase(new URL(obr))
+            .addGatewayRepository(new URL(hostName + endpoint), customerName, gatewayRepo, true)
+            .addDeploymentRepository(new URL(hostName + endpoint), customerName, deployRepo, true);
+            m_admin.login(context);
+            m_admin.checkout();
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+        }
+        
+        setTheme("reindeer");
+        final Window main = new Window("Apache ACE - Bazaar Manager - " + this);
+        setMainWindow(main);
+        main.getContent().setSizeFull();
+        
+        final GridLayout grid = new GridLayout(1, 2);
+        grid.setSpacing(true);
+
+        grid.setWidth(100, Sizeable.UNITS_PERCENTAGE);
+        grid.setHeight(100, Sizeable.UNITS_PERCENTAGE);
+
+        // toolbar
+        GridLayout toolbar = new GridLayout(3,1);
+        toolbar.setSpacing(true);
+        
+        Button retrieveButton = new Button("Retrieve");
+        retrieveButton.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                try {
+                    m_admin.checkout();
+                    System.out.println("checkout");
+                    updateTableData();
+                }
+                catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        });
+        toolbar.addComponent(retrieveButton, 0, 0);
+        
+        Button storeButton = new Button("Store");
+        storeButton.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                try {
+                    m_admin.commit();
+                    System.out.println("commit");
+                    updateTableData();
+                }
+                catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        });
+        toolbar.addComponent(storeButton, 1, 0);
+        Button revertButton = new Button("Revert");
+        revertButton.addListener(new Button.ClickListener() {
+            public void buttonClick(ClickEvent event) {
+                try {
+                    m_admin.revert();
+                    System.out.println("revert");
+                    updateTableData();
+                }
+                catch (IOException e) {
+                    // TODO Auto-generated catch block
+                    e.printStackTrace();
+                }
+            }
+        });
+        toolbar.addComponent(revertButton, 2, 0);
+        
+        grid.addComponent(toolbar, 0, 0);
+        
+        m_distributionsPanel = new Panel();
+        VerticalLayout layout = new VerticalLayout();
+        layout.setSpacing(true);
+        layout.setMargin(true);
+        m_distributionsPanel.setContent(layout);
+        m_distributionsPanel.setSizeFull();
+        m_distributionsPanel.setWidth(800, Sizeable.UNITS_PIXELS);
+        grid.setRowExpandRatio(1, 1.0f);
+        
+        grid.addComponent(m_distributionsPanel, 0, 1);
+        
+        updateTableData();
+        
+        main.addComponent(grid);
+    }
+    
+    /**
+     * Panel representing a single distribution (license), allowing editing.
+     * TODO we probably could do this way smarter using Properties and Items
+     */
+    private class DistributionPanel extends Panel {
+		private static final long serialVersionUID = 1L;
+		
+		private final LicenseObject m_license;
+		private Embedded m_icon;
+
+		public DistributionPanel(LicenseObject license) {
+			super(license.getName());
+			m_license = license;
+			setContent();
+    	}
+
+		private void setContent() {
+			GridLayout grid = new GridLayout(3, 2);
+			setContent(grid);
+			grid.setSpacing(true);
+			grid.setColumnExpandRatio(1, 1.0f);
+			grid.setColumnExpandRatio(2, 1.0f);
+			grid.setSizeFull();
+			String icon = m_license.getTag("icon");
+			m_icon = new Embedded("", icon == null ? new ThemeResource("../runo/icons/64/document.png") : new ExternalResource(icon));
+			grid.addComponent(m_icon, 0, 0);
+			
+	        TextField description = new TextField("", m_license.getDescription() == null ? "" : m_license.getDescription());
+	        description.setImmediate(true);
+	        description.setRows(5);
+	        description.setWidth(100, Sizeable.UNITS_PERCENTAGE);
+	        description.addListener(new Property.ValueChangeListener() {
+	            public void valueChange(ValueChangeEvent event) {
+	            	String value = (String) event.getProperty().getValue();
+	            	m_license.setDescription(value);
+	            }
+	        });
+	        grid.addComponent(description, 1, 0, 2, 0);
+	        
+	        CheckBox visible = new CheckBox("Show in Bazaar", "true".equals(m_license.getTag("bazaar")));
+	        visible.setImmediate(true);
+	        visible.addListener(new Property.ValueChangeListener() {
+	            public void valueChange(ValueChangeEvent event) {
+	            	m_license.addTag("bazaar", "" + (((Boolean) event.getProperty().getValue()) ? "true" : "false"));
+	            }
+	        });
+	        grid.addComponent(visible, 1, 1);
+	        
+	        Label installed = new Label("Installed on " + m_license.getAssociations(GatewayObject.class).size() + " devices.");
+			grid.addComponent(installed, 2, 1);
+	        grid.setComponentAlignment(installed, Alignment.MIDDLE_RIGHT);
+
+	        Button iconButton = new Button("icon...");
+	        grid.addComponent(iconButton, 0, 1);
+	        
+			iconButton.addListener(new Button.ClickListener() {
+				public void buttonClick(ClickEvent event) {
+					IconWindow window = new IconWindow(m_license);
+					getMainWindow().addWindow(window);
+				}
+			});
+		}
+
+		/**
+		 * Helper window, which allows the user to set an icon for a given license.
+		 */
+		private class IconWindow extends Window {
+			public IconWindow(final LicenseObject license) {
+				setModal(true);
+				setWidth(350, UNITS_PIXELS);
+
+				VerticalLayout layout = new VerticalLayout();
+				layout.setSizeFull();
+				layout.setSpacing(true);
+				layout.setMargin(true);
+				setContent(layout);
+
+				final TextField textField = new TextField("", license.getTag("icon"));
+				textField.setImmediate(true);
+				addComponent(textField);
+				textField.setWidth(100, Sizeable.UNITS_PERCENTAGE);
+				layout.setExpandRatio(textField, 1.0f);
+				layout.setComponentAlignment(textField, Alignment.MIDDLE_LEFT);
+				
+				Button ok = new Button("OK");
+				addComponent(ok);
+				layout.setComponentAlignment(ok, Alignment.MIDDLE_RIGHT);
+				
+				ok.addListener(new Button.ClickListener() {
+					public void buttonClick(ClickEvent event) {
+						license.addTag("icon", (String) textField.getValue());
+						m_icon.setSource(new ExternalResource((String) textField.getValue()));
+						IconWindow.this.close();
+					}
+				});
+	    	}
+	    }
+    }
+
+    private void updateTableData() {
+        m_distributions = m_distributionRepository.get();
+        
+        m_distributionsPanel.removeAllComponents();
+        
+        for (LicenseObject license : m_distributions) {
+        	m_distributionsPanel.addComponent(new DistributionPanel(license));
+        }
+    }
+    
+    @Override
+    public void close() {
+        super.close();
+        // when the session times out
+        // TODO: clean up the ace client session?
+    }
+}
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/bazaar/VaadinServlet.java
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/bazaar/VaadinServlet.java?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/bazaar/VaadinServlet.java (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/java/org/apache/ace/webui/vaadin/bazaar/VaadinServlet.java Thu Nov  4 21:28:26 2010
@@ -0,0 +1,46 @@
+package org.apache.ace.webui.vaadin.bazaar;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.ace.client.repository.SessionFactory;
+import org.apache.felix.dm.DependencyManager;
+import org.osgi.service.log.LogService;
+import org.osgi.service.useradmin.UserAdmin;
+
+import com.vaadin.Application;
+import com.vaadin.terminal.gwt.server.AbstractApplicationServlet;
+
+public class VaadinServlet extends AbstractApplicationServlet {
+	private static final long serialVersionUID = 1L;
+
+	private volatile DependencyManager m_manager;
+    
+    @Override
+    protected Class<? extends Application> getApplicationClass() {
+        return BazaarManager.class;
+    }
+
+    @Override
+    protected Application getNewApplication(HttpServletRequest request)	throws ServletException {
+        Application application = new BazaarManager();
+        m_manager.add(m_manager.createComponent()
+            .setImplementation(application)
+            .setCallbacks("setupDependencies", "start", "stop", "destroyDependencies")
+            .add(m_manager.createServiceDependency()
+                .setService(SessionFactory.class)
+                .setRequired(true)
+                )
+            .add(m_manager.createServiceDependency()
+                .setService(UserAdmin.class)
+                .setRequired(true)
+                )
+            .add(m_manager.createServiceDependency()
+                .setService(LogService.class)
+                .setRequired(false)
+                )
+            );
+        
+        return application;
+    }
+}
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/a-sprite-definitions/a-sprite-definitions.css
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/a-sprite-definitions/a-sprite-definitions.css?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/a-sprite-definitions/a-sprite-definitions.css (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/a-sprite-definitions/a-sprite-definitions.css Thu Nov  4 21:28:26 2010
@@ -0,0 +1,14 @@
+/*------------
+ * General vertical and horizontal sprites 
+ * -----------*/
+/** sprite: verticals; sprite-image: url(../common/img/vertical-sprites.png); sprite-layout: vertical */
+/** sprite: horizontals; sprite-image: url(../common/img/horizontal-sprites.png); sprite-layout: horizontal */
+
+/** sprite: black-verticals; sprite-image: url(../common/img/black-vertical-sprites.png); sprite-layout: vertical; sprite-matte-color: #1e2022 */
+/** sprite: black-horizontals; sprite-image: url(../common/img/black-horizontal-sprites.png); sprite-layout: horizontal; sprite-matte-color: #1e2022 */
+
+/*------------
+ * Buttons 
+ * -----------*/
+/** sprite: buttons; sprite-image: url(../button/img/button-sprites.png); sprite-layout: vertical */
+/** sprite: black-buttons; sprite-image: url(../button/img/black-button-sprites.png); sprite-layout: vertical */
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/accordion/accordion.css
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/accordion/accordion.css?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/accordion/accordion.css (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/accordion/accordion.css Thu Nov  4 21:28:26 2010
@@ -0,0 +1,45 @@
+.v-accordion {
+	border: 1px solid #bebebe;
+	border-radius: 2px;
+	-webkit-border-radius: 2px;
+	-moz-border-radius: 2px;
+	overflow: hidden;
+}
+.v-accordion-item {
+	background-color: #fff;
+}
+.v-accordion-item-caption {
+	height: 19px;
+	background: #e4e4e4 repeat-x;
+	background-image: url(../tabsheet/img/tabbar-bg.png); /** sprite-ref: verticals; sprite-alignment: repeat */
+	font-size: 11px;
+	line-height: normal;
+	border-top: 1px solid #bebebe;
+	text-shadow: #fff 0 1px 0;
+}
+.v-accordion-item-first .v-accordion-item-caption {
+	border-top: none;
+}
+.v-accordion-item-caption .v-caption {
+	padding: 3px 0 5px 10px;
+}
+.v-ie .v-accordion-item-caption .v-caption {
+	padding: 2px 0 6px 10px;
+}
+.v-accordion-item-open .v-accordion-item-caption {
+	background-image: url(../tabsheet/img/tabbar-bg-sel.png); /** sprite-ref: verticals; sprite-alignment: repeat */
+	border-bottom: 1px solid #bbb;
+}
+.v-accordion-item-caption .v-icon {
+	margin-top: -1px;
+}
+.v-ie .v-accordion-item-caption .v-icon {
+	vertical-align: top;
+}
+/* Borderless style */
+.v-accordion-borderless {
+	border: none;
+	border-radius: 0;
+	-webkit-border-radius: 0;
+	-moz-border-radius: 0;
+}
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-firefox.css
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-firefox.css?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-firefox.css (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-firefox.css Thu Nov  4 21:28:26 2010
@@ -0,0 +1,5 @@
+.v-ff2 .v-button .v-button-caption {
+	display: -moz-inline-box;
+	padding-top: 6px;
+	height: 20px;
+	}
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-ie.css
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-ie.css?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-ie.css (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-ie.css Thu Nov  4 21:28:26 2010
@@ -0,0 +1,75 @@
+.v-ie6 .v-nativebutton-link,
+.v-ie7 .v-nativebutton-link,
+.v-ie8 .v-nativebutton-link {
+	padding: 0;
+	text-align: left;
+}
+
+/**
+ * IE6 buttons --------------------------
+ */
+.v-ie6 .v-button {
+	border: 1px solid #b3b3b3;
+	border-bottom-color: #9a9a9a;
+	background: #d8d8d8 url(img/right.png) no-repeat 0 -1px;
+	padding: 0 15px;
+	height: 23px;
+}
+.v-ie6 .v-button .v-button-wrap {
+	background: transparent;
+	height: 20px;
+	padding: 3px 0 0;
+	display: inline;
+	zoom: 1;
+}
+.v-ie6 .v-button-primary {
+	background-image: url(img/primary-right.png);
+}
+.v-ie6 .v-button-small {
+	background-image: url(img/small-right.png);
+	height: 17px;
+}
+.v-ie6 .v-button-small .v-button-wrap {
+	height: 17px;
+	padding: 0;
+}
+.v-ie6 .v-button.v-pressed {
+	background: transparent url(img/right-pressed.png) no-repeat 0 -1px;
+}
+/* Buttons on blue background */
+.v-ie6 .blue .v-button {
+	border-color: #84949c;
+	border-top-color: #83939b;
+	border-bottom-color: #888d91;
+}
+/* Buttons on black background */
+.v-ie6 .black .v-button {
+	border: 1px solid #0d0e0f;
+	background: #202224 url(img/black/right.png) no-repeat 0 -1px;
+	color: #c9ccce;
+}
+.v-ie6 .black .v-button-primary {
+	background-image: url(img/black/primary-right.png);
+}
+.v-ie6 .black .v-button-small {
+	background-image: url(img/black/small-right.png);
+}
+.v-ie6 .black .v-button.v-pressed {
+	background-image: url(img/black/right-pressed.png);
+}
+
+
+/* Link style button */
+.v-ie6 .v-button-link,
+.v-ie6 .black .v-button-link {
+	background: transparent;
+	border: none;
+	height: auto;
+	line-height: normal;
+	padding: 0;
+}
+.v-ie6 .v-button-link .v-button-wrap,
+.v-ie6 .black .v-button-link .v-button-wrap {
+	padding: 0;
+	height: auto;
+}
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-link-style.css
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-link-style.css?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-link-style.css (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-link-style.css Thu Nov  4 21:28:26 2010
@@ -0,0 +1,35 @@
+.v-button.v-button-link,
+.v-button.v-button-link:focus,
+.v-button.v-button-link:active,
+.v-button-link.v-pressed,
+.v-disabled.v-button.v-button-link,
+.v-button.v-button-link .v-button-wrap,
+.v-button.v-button-link:focus .v-button-wrap,
+.v-button.v-button-link:active .v-button-wrap,
+.v-button-link.v-pressed .v-button-wrap,
+.v-disabled.v-button.v-button-link .v-button-wrap {
+	background: transparent;
+	height: auto;
+	padding: 0;
+	cursor: pointer;
+	line-height: inherit;
+	}
+
+.v-button.v-button-link.v-disabled,
+.v-button.v-button-link.v-disabled .v-button-wrap {
+	cursor: default;
+	}
+	
+.v-button-link .v-button-caption,
+.v-nativebutton-link .v-nativebutton-caption {
+	line-height: inherit;
+	font-weight: normal;
+	color: #1b699f;
+	font-size: 12px;
+	text-shadow: none;
+	}
+	
+.v-button-link:focus .v-button-caption,
+.v-nativebutton-link:focus .v-nativebutton-caption {
+	outline: 1px dotted #1b699f;
+	}
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-primary-style.css
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-primary-style.css?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-primary-style.css (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-primary-style.css Thu Nov  4 21:28:26 2010
@@ -0,0 +1,62 @@
+.v-button-primary:focus {
+	background-image: url(img/primary-left-focus.png); /** sprite-ref: buttons */
+	}
+	
+.v-button-primary:focus .v-button-wrap {
+	background-image: url(img/primary-right-focus.png); /** sprite-ref: buttons; sprite-alignment: right */
+	}
+	
+.v-button-primary:active,
+.v-button-primary.v-pressed {
+	background-image: url(img/primary-left-pressed.png); /** sprite-ref: buttons */
+	}
+
+.v-button-primary:active .v-button-wrap,
+.v-button-primary.v-pressed .v-button-wrap {
+	background-image: url(img/primary-right-pressed.png); /** sprite-ref: buttons; sprite-alignment: right */
+	}
+
+.v-button-primary,
+.v-disabled.v-button-primary {
+	background-image: url(img/primary-left.png); /** sprite-ref: buttons */
+	}
+	
+.v-button-primary .v-button-wrap,
+.v-disabled.v-button-primary .v-button-wrap {
+	background-image: url(img/primary-right.png); /** sprite-ref: buttons; sprite-alignment: right */
+	}
+	
+
+
+
+/* Black style */
+
+
+.black .v-button-primary:focus {
+	background-image: url(img/black/primary-left-focus.png); /** sprite-ref: black-buttons */
+	}
+	
+.black .v-button-primary:focus .v-button-wrap {
+	background-image: url(img/black/primary-right-focus.png); /** sprite-ref: black-buttons; sprite-alignment: right */
+	color: #eaf4fb;
+	}
+	
+.black .v-button-primary:active,
+.black .v-button-primary.v-pressed {
+	background-image: url(img/black/primary-left-pressed.png); /** sprite-ref: black-buttons */
+	}
+	
+.black .v-button-primary:active .v-button-wrap,
+.black .v-button-primary.v-pressed .v-button-wrap {
+	background-image: url(img/black/primary-right-pressed.png); /** sprite-ref: black-buttons; sprite-alignment: right */
+	}
+
+.black .v-button-primary,
+.black .v-disabled.v-button-primary {
+	background-image: url(img/black/primary-left.png); /** sprite-ref: black-buttons */
+	}
+	
+.black .v-button-primary .v-button-wrap,
+.black .v-disabled.v-button-primary .v-button-wrap {
+	background-image: url(img/black/primary-right.png); /** sprite-ref: black-buttons; sprite-alignment: right */
+	}

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-small-style.css
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-small-style.css?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-small-style.css (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-small-style.css Thu Nov  4 21:28:26 2010
@@ -0,0 +1,67 @@
+.v-button-small:focus {
+	background-image: url(img/small-left-focus.png); /** sprite-ref: buttons */
+	}
+	
+.v-button-small:focus .v-button-wrap {
+	background-image: url(img/small-right-focus.png); /** sprite-ref: buttons; sprite-alignment: right */
+	}
+	
+.v-button-small:active,
+.v-button-small.v-pressed {
+	background-image: url(img/small-left-pressed.png); /** sprite-ref: buttons */
+	}
+
+.v-button-small:active .v-button-wrap,
+.v-button-small.v-pressed .v-button-wrap {
+	background-image: url(img/small-right-pressed.png); /** sprite-ref: buttons; sprite-alignment: right */
+	}
+
+.v-button-small,
+.v-disabled.v-button-small {
+	background-image: url(img/small-left.png); /** sprite-ref: buttons */
+	height: 20px;
+	}
+	
+.v-button-small .v-button-wrap,
+.v-disabled.v-button-small .v-button-wrap {
+	background-image: url(img/small-right.png); /** sprite-ref: buttons; sprite-alignment: right */
+	height: 19px;
+	padding: 1px 14px 0 8px;
+	}
+
+.v-button-small .v-button-caption {
+	font-weight: normal;
+	}
+	
+
+
+
+/* Black style */
+
+.black .v-button-small:focus {
+	background-image: url(img/black/small-left-focus.png); /** sprite-ref: black-buttons */
+	}
+	
+.black .v-button-small:focus .v-button-wrap {
+	background-image: url(img/black/small-right-focus.png); /** sprite-ref: black-buttons; sprite-alignment: right */
+	}
+	
+.black .v-button-small:active,
+.black .v-button-small.v-pressed {
+	background-image: url(img/black/small-left-pressed.png); /** sprite-ref: black-buttons */
+	}
+	
+.black .v-button-small:active .v-button-wrap,
+.black .v-button-small.v-pressed .v-button-wrap {
+	background-image: url(img/black/small-right-pressed.png); /** sprite-ref: black-buttons; sprite-alignment: right */
+	}
+
+.black .v-button-small,
+.black .v-disabled.v-button-small {
+	background-image: url(img/black/small-left.png); /** sprite-ref: black-buttons */
+	}
+	
+.black .v-button-small .v-button-wrap,
+.black .v-disabled.v-button-small .v-button-wrap {
+	background-image: url(img/black/small-right.png); /** sprite-ref: black-buttons; sprite-alignment: right */
+	}
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-standard.css
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-standard.css?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-standard.css (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button-standard.css Thu Nov  4 21:28:26 2010
@@ -0,0 +1,90 @@
+.v-button:focus {
+	background-image: url(img/left-focus.png); /** sprite-ref: buttons */
+	outline: none;
+	}
+
+.v-button:focus .v-button-wrap {
+	background-image: url(img/right-focus.png); /** sprite-ref: buttons; sprite-alignment: right */
+	outline: none;
+	}
+
+.v-button:active,
+.v-button.v-pressed {
+	background-image: url(img/left-pressed.png); /** sprite-ref: buttons */
+	outline: none;
+	}
+
+.v-button:active .v-button-wrap,
+.v-button.v-pressed .v-button-wrap {
+	background-image: url(img/right-pressed.png); /** sprite-ref: buttons; sprite-alignment: right */
+	outline: none;
+	}
+
+.v-button,
+.v-disabled.v-button {
+	height: 26px;
+	padding: 0 0 0 6px;
+	background-color: transparent;
+	background-repeat: no-repeat;
+	background-image: url(img/left.png); /** sprite-ref: buttons */
+	border: none;
+	cursor: default;
+	}
+
+.v-button-wrap,
+.v-disabled.v-button .v-button-wrap {
+	display: block;
+	height: 22px;
+	padding: 4px 15px 0 9px;
+	background-color: transparent;
+	background-repeat: no-repeat;
+	background-position: right top;
+	background-image: url(img/right.png);  /** sprite-ref: buttons; sprite-alignment: right */
+	}
+
+.v-button-caption {
+	color: #222;
+	text-shadow: #fff 0 1px 0;
+	font-weight: bold;
+	font-size: 11px;
+	line-height: 16px;
+	}
+
+
+
+
+/**************************
+ * Black style
+ **************************/
+.black .v-button:focus {
+	background-image: url(img/black/left-focus.png); /** sprite-ref: black-buttons */
+	}
+	
+.black .v-button:focus .v-button-wrap {
+	background-image: url(img/black/right-focus.png); /** sprite-ref: black-buttons; sprite-alignment: right */
+	}
+	
+.black .v-button:active,
+.black .v-button.v-pressed {
+	background-image: url(img/black/left-pressed.png); /** sprite-ref: black-buttons */
+	}
+	
+.black .v-button:active .v-button-wrap,
+.black .v-button.v-pressed .v-button-wrap {
+	background-image: url(img/black/right-pressed.png); /** sprite-ref: black-buttons; sprite-alignment: right */
+	}
+
+.black .v-button,
+.black .v-disabled.v-button {
+	background-image: url(img/black/left.png); /** sprite-ref: black-buttons */
+	}
+	
+.black .v-button-wrap,
+.black .v-disabled.v-button .v-button-wrap {
+	background-image: url(img/black/right.png); /** sprite-ref: black-buttons; sprite-alignment: right */
+	}
+	
+.black .v-button-caption {
+	color: #c9ccce;
+	text-shadow: #121314 0 -1px 0;
+	}
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button.css
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button.css?rev=1031262&view=auto
==============================================================================
--- incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button.css (added)
+++ incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/button.css Thu Nov  4 21:28:26 2010
@@ -0,0 +1,11 @@
+/* Standard implementation of the button theme
+ * These files contain styles that apply to all browsers
+ */
+@import "button-standard.css";
+@import "button-primary-style.css";
+@import "button-small-style.css";
+@import "button-link-style.css";
+
+/* Browser-specific corrections to the standard implementation */
+@import "button-firefox.css";
+@import "button-ie.css";
\ No newline at end of file

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black-button-sprites-ie6.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black-button-sprites-ie6.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black-button-sprites-ie6.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black-button-sprites.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black-button-sprites.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black-button-sprites.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/left-focus.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/left-focus.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/left-focus.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/left-pressed.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/left-pressed.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/left-pressed.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/left.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/left.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/left.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-left-focus.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-left-focus.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-left-focus.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-left-pressed.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-left-pressed.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-left-pressed.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-left.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-left.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-left.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-right-focus.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-right-focus.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-right-focus.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-right-pressed.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-right-pressed.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-right-pressed.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-right.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-right.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/primary-right.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/right-focus.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/right-focus.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/right-focus.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/right-pressed.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/right-pressed.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/right-pressed.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/right.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/right.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/right.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-left-focus.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-left-focus.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-left-focus.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-left-pressed.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-left-pressed.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-left-pressed.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-left.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-left.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-left.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-right-focus.png
URL: http://svn.apache.org/viewvc/incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-right-focus.png?rev=1031262&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/ace/trunk/ace-webui-vaadin/src/main/resources/VAADIN/themes/ace/button/img/black/small-right-focus.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream