Refactor distribution Overview Page and add a filter
authorBruno Sinou <bsinou@argeo.org>
Wed, 6 Mar 2013 12:19:01 +0000 (12:19 +0000)
committerBruno Sinou <bsinou@argeo.org>
Wed, 6 Mar 2013 12:19:01 +0000 (12:19 +0000)
git-svn-id: https://svn.argeo.org/slc/trunk@6104 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc

plugins/org.argeo.slc.client.ui.dist/src/main/java/org/argeo/slc/client/ui/dist/editors/DistributionOverviewPage.java

index 1f48220560bf5f580220c8fe07b1fd3ba3171e1f..c2af792367150ab510c8ddd1ee0fa65fe81635e0 100644 (file)
@@ -23,15 +23,21 @@ import javax.jcr.NodeIterator;
 import javax.jcr.PropertyType;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.jcr.query.Query;
 import javax.jcr.query.QueryManager;
 import javax.jcr.query.QueryResult;
+import javax.jcr.query.qom.Constraint;
+import javax.jcr.query.qom.DynamicOperand;
 import javax.jcr.query.qom.Ordering;
 import javax.jcr.query.qom.QueryObjectModel;
 import javax.jcr.query.qom.QueryObjectModelFactory;
 import javax.jcr.query.qom.Selector;
+import javax.jcr.query.qom.StaticOperand;
 
-import org.argeo.eclipse.ui.ErrorFeedback;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.argeo.jcr.JcrUtils;
+import org.argeo.slc.SlcException;
 import org.argeo.slc.client.ui.dist.DistPlugin;
 import org.argeo.slc.client.ui.dist.commands.DeleteArtifacts;
 import org.argeo.slc.client.ui.dist.utils.CommandHelpers;
@@ -47,27 +53,43 @@ import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.TableViewerColumn;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
 import org.eclipse.ui.IWorkbenchWindow;
 import org.eclipse.ui.forms.IManagedForm;
 import org.eclipse.ui.forms.editor.FormEditor;
 import org.eclipse.ui.forms.editor.FormPage;
+import org.eclipse.ui.forms.widgets.FormToolkit;
 import org.eclipse.ui.forms.widgets.ScrolledForm;
+import org.eclipse.ui.forms.widgets.Section;
 import org.osgi.framework.Constants;
 
-/** Table giving an overview of an OSGi distribution */
+/** Table giving an overview of an OSGi distribution with corresponding filters */
 public class DistributionOverviewPage extends FormPage implements SlcNames {
        final static String PAGE_ID = "distributionOverviewPage";
+       final private static Log log = LogFactory
+                       .getLog(DistributionOverviewPage.class);
 
-       private TableViewer viewer;
+       // Business Objects
        private Session session;
 
+       // This page widgets
        private NodeViewerComparator comparator;
+       private TableViewer viewer;
+       private Text artifactTxt;
+       private FormToolkit tk;
+       private Composite header;
+       private Section headerSection;
 
        public DistributionOverviewPage(FormEditor formEditor, String title,
                        Session session) {
@@ -78,15 +100,100 @@ public class DistributionOverviewPage extends FormPage implements SlcNames {
        @Override
        protected void createFormContent(IManagedForm managedForm) {
                ScrolledForm form = managedForm.getForm();
+               tk = managedForm.getToolkit();
+
+               // Main Layout
                GridLayout layout = new GridLayout(1, false);
-               form.getBody().setLayout(layout);
+               Composite body = form.getBody();
+               body.setLayout(layout);
+
+               // Add the filter section
+               createFilterPart(body);
+               // Add the table
+               createTableViewer(body);
+
+               // Add a listener to enable custom resize process
+               form.addControlListener(new ControlListener() {
+                       public void controlResized(ControlEvent e) {
+                               refreshLayout();
+                       }
+
+                       public void controlMoved(ControlEvent e) {
+                       }
+               });
+
+               // This below doesn not work; the listener must be added as a control
+               // listener to be correctly notified when resize events happen
+
+               // form.addListener(SWT.RESIZE, new Listener() {
+               // public void handleEvent(Event event) {
+               // log.debug("Form resized ....");
+               // }
+               // });
+
+       }
+
+       private void createFilterPart(Composite parent) {
+               header = tk.createComposite(parent);
+               GridLayout layout = new GridLayout(2, false);
+               header.setLayout(layout);
+               GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false);
+               header.setLayoutData(gd);
+
+               // Artifact Name
+               tk.createLabel(header, "Artifact name: ", SWT.NONE);
+               artifactTxt = tk.createText(header, "", SWT.BORDER | SWT.SINGLE);
+               gd = new GridData(SWT.FILL, SWT.FILL, false, false);
+               gd.grabExcessHorizontalSpace = true;
+               artifactTxt.setLayoutData(gd);
+               artifactTxt.addModifyListener(new ModifyListener() {
+
+                       public void modifyText(ModifyEvent event) {
+                               refreshFilteredList();
+                       }
+               });
+
+               headerSection = tk.createSection(header, Section.TWISTIE);
+               headerSection.setText("Advanced filters");
+               headerSection.setExpanded(false);
+               gd = new GridData(SWT.FILL, SWT.FILL, false, false);
+               gd.horizontalSpan = 2;
+               headerSection.setLayoutData(gd);
+
+               Composite body = new Composite(headerSection, SWT.FILL);
+               headerSection.setClient(body);
+
+               // Layout
+               layout = new GridLayout(2, false);
+               body.setLayout(layout);
+
+               // Artifact Name
+               tk.createLabel(body, "Add some more filters here ", SWT.NONE);
+               // lbl = tk.createLabel(body, "Artifact name: ", SWT.NONE);
+               // artifactTxt = tk.createText(body, "", SWT.BORDER | SWT.SINGLE);
+               // gd = new GridData(SWT.FILL, SWT.FILL, false, false);
+               // gd.grabExcessHorizontalSpace = true;
+               // artifactTxt.setLayoutData(gd);
+               // artifactTxt.addModifyListener(new ModifyListener() {
+               //
+               // public void modifyText(ModifyEvent event) {
+               // refreshFilteredList();
+               // }
+               // });
+       }
+
+       private void refreshFilteredList() {
+               viewer.refresh();
+       }
+
+       private void createTableViewer(Composite parent) {
 
                // helpers to enable sorting by column
                List<String> propertiesList = new ArrayList<String>();
                List<Integer> propertyTypesList = new ArrayList<Integer>();
 
                // Define the TableViewer
-               viewer = new TableViewer(form.getBody(), SWT.MULTI | SWT.H_SCROLL
+               viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
                                | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
 
                TableViewerColumn col = new TableViewerColumn(viewer, SWT.V_SCROLL);
@@ -145,7 +252,9 @@ public class DistributionOverviewPage extends FormPage implements SlcNames {
                final Table table = viewer.getTable();
                table.setHeaderVisible(true);
                table.setLinesVisible(true);
-               table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+               GridData gd = new GridData(SWT.FILL, SWT.TOP, true, true);
+               gd.heightHint = 300;
+               table.setLayoutData(gd);
 
                viewer.setContentProvider(new DistributionsContentProvider());
                getSite().setSelectionProvider(viewer);
@@ -178,6 +287,41 @@ public class DistributionOverviewPage extends FormPage implements SlcNames {
                viewer.refresh();
        }
 
+       /**
+        * UI Trick to put scroll bar on the table rather than on the scrollform
+        */
+       private void refreshLayout() {
+               // Compute desired table size
+               int maxH = getManagedForm().getForm().getSize().y;
+               int maxW = getManagedForm().getForm().getParent().getSize().x;
+               // int maxW = getManagedForm().getForm().getSize().x;
+               maxH = maxH - header.getSize().y;
+
+               // maxH = maxH - headerSection.getSize().y
+               // - headerSection.getClient().getSize().y;
+
+               // Set
+               final Table table = viewer.getTable();
+               GridData gd = new GridData(SWT.LEFT, SWT.TOP, true, true);
+               // when table height is less than 200 px, we let the scroll bar on the
+               // scrollForm
+
+               // FIXME substract some spare space. Here is room for optimization
+               gd.heightHint = Math.max(maxH - 70, 200);
+               gd.widthHint = Math.max(maxW - 40, 200);
+
+               table.setLayoutData(gd);
+               getManagedForm().reflow(true);
+       }
+
+       @Override
+       public void setActive(boolean active) {
+               super.setActive(active);
+               if (active) {
+                       refreshLayout();
+               }
+       }
+
        /** Programatically configure the context menu */
        protected void contextMenuAboutToShow(IMenuManager menuManager) {
                IWorkbenchWindow window = DistPlugin.getDefault().getWorkbench()
@@ -192,7 +336,7 @@ public class DistributionOverviewPage extends FormPage implements SlcNames {
 
        }
 
-       static NodeIterator listBundleArtifacts(Session session)
+       NodeIterator listBundleArtifacts(Session session)
                        throws RepositoryException {
                QueryManager queryManager = session.getWorkspace().getQueryManager();
                QueryObjectModelFactory factory = queryManager.getQOMFactory();
@@ -201,17 +345,61 @@ public class DistributionOverviewPage extends FormPage implements SlcNames {
                Selector source = factory.selector(SlcTypes.SLC_BUNDLE_ARTIFACT,
                                bundleArtifactsSelector);
 
+               String artifactTxtVal = artifactTxt.getText();
+
+               DynamicOperand propName = factory.propertyValue(
+                               source.getSelectorName(), SlcNames.SLC_SYMBOLIC_NAME);
+               StaticOperand propValue = factory.bindVariable("'%" + artifactTxtVal
+                               + "%'");
+               Constraint constraint = factory.comparison(propName,
+                               QueryObjectModelFactory.JCR_OPERATOR_LIKE, propValue);
+
                Ordering order = factory.ascending(factory.propertyValue(
                                bundleArtifactsSelector, SlcNames.SLC_SYMBOLIC_NAME));
                Ordering[] orderings = { order };
 
-               QueryObjectModel query = factory.createQuery(source, null, orderings,
-                               null);
+               QueryObjectModel query = factory.createQuery(source, constraint,
+                               orderings, null);
 
                QueryResult result = query.execute();
                return result.getNodes();
        }
 
+       private NodeIterator getArtifactsWithWhereClause(String whereClause) {
+               StringBuffer strBuf = new StringBuffer();
+               strBuf.append("Select * FROM [" + SlcTypes.SLC_BUNDLE_ARTIFACT
+                               + "] AS bundleArtifacts");
+               if (whereClause != null && !"".equals(whereClause.trim())) {
+                       strBuf.append(" WHERE ");
+                       strBuf.append(whereClause);
+               }
+               strBuf.append(" ORDER BY ");
+               strBuf.append("bundleArtifacts.[" + SlcNames.SLC_SYMBOLIC_NAME + "] ");
+               strBuf.append("ASC");
+               try {
+                       if (log.isTraceEnabled())
+                               log.trace("Get artifacts query : " + strBuf.toString());
+                       Query query = session.getWorkspace().getQueryManager()
+                                       .createQuery(strBuf.toString(), Query.JCR_SQL2);
+                       return query.execute().getNodes();
+               } catch (RepositoryException e) {
+                       throw new SlcException(
+                                       "Unexpected error while retrieving list of artifacts", e);
+               }
+       }
+
+       private String buildWhereClause() {
+               StringBuffer whereClause = new StringBuffer();
+
+               String artifactTxtVal = artifactTxt.getText();
+               if (!"".equals(artifactTxtVal)) {
+                       whereClause.append("bundleArtifacts.[" + SlcNames.SLC_SYMBOLIC_NAME
+                                       + "] like ");
+                       whereClause.append("'%" + artifactTxtVal + "%'");
+               }
+               return whereClause.toString();
+       }
+
        private SelectionAdapter getSelectionAdapter(final int index) {
                SelectionAdapter selectionAdapter = new SelectionAdapter() {
                        @Override
@@ -232,26 +420,30 @@ public class DistributionOverviewPage extends FormPage implements SlcNames {
                return selectionAdapter;
        }
 
-       private static class DistributionsContentProvider implements
+       private class DistributionsContentProvider implements
                        IStructuredContentProvider {
-               private Session session;
+               // private Session session;
 
                public void dispose() {
                }
 
                public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
-                       session = (Session) newInput;
+                       // session = (Session) newInput;
                }
 
                public Object[] getElements(Object arg0) {
-                       try {
-                               List<Node> nodes = JcrUtils
-                                               .nodeIteratorToList(listBundleArtifacts(session));
-                               return nodes.toArray();
-                       } catch (RepositoryException e) {
-                               ErrorFeedback.show("Cannot list bundles", e);
-                               return null;
-                       }
+                       // try {
+                       // List<Node> nodes = JcrUtils
+                       // .nodeIteratorToList(listBundleArtifacts(session));
+                       // return nodes.toArray();
+                       // } catch (RepositoryException e) {
+                       // ErrorFeedback.show("Cannot list bundles", e);
+                       // return null;
+                       // }
+
+                       List<Node> nodes = JcrUtils
+                                       .nodeIteratorToList(getArtifactsWithWhereClause(buildWhereClause()));
+                       return nodes.toArray();
                }
        }
        //