/* * � Copyright IBM Corp. 2010 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package com.ibm.xsp.extlib.tree.complex; import java.util.Arrays; import java.util.Comparator; import java.util.Iterator; import java.util.Vector; import javax.faces.context.FacesContext; import javax.faces.el.ValueBinding; import lotus.domino.Database; import lotus.domino.NotesException; import lotus.domino.View; import com.ibm.commons.util.StringUtil; import com.ibm.xsp.FacesExceptionEx; import com.ibm.xsp.extlib.tree.ITreeNode; import com.ibm.xsp.extlib.tree.impl.TreeNodeWrapper; import com.ibm.xsp.model.domino.DominoUtils; /** * Specific tree that returns the list of view/folders in a database. * * @author Philippe Riand */ public class ViewListTreeNode extends ComplexLeafTreeNode { private static final long serialVersionUID = 1L; private String databaseName; private String filter; private String var; private Boolean views; private Boolean folders; public ViewListTreeNode() { } @Override public int getType() { return NODE_NODELIST; } public String getDatabaseName() { if (databaseName != null) { return databaseName; } ValueBinding vb = getValueBinding("databaseName"); //$NON-NLS-1$ if (vb != null) { return (String) vb.getValue(getFacesContext()); } return null; } public void setDatabaseName(String databaseName) { this.databaseName = databaseName; } public String getFilter() { if (filter != null) { return filter; } ValueBinding vb = getValueBinding("filter"); //$NON-NLS-1$ if (vb != null) { return (String) vb.getValue(getFacesContext()); } return null; } public void setFilter(String filter) { this.filter = filter; } public String getVar() { return var; } public void setVar(String var) { this.var = var; } public boolean isViews() { if (null != this.views) { return this.views; } ValueBinding _vb = getValueBinding("views"); //$NON-NLS-1$ if (_vb != null) { Boolean val = (java.lang.Boolean) _vb.getValue(FacesContext.getCurrentInstance()); if (val != null) { return val; } } return true; } public void setViews(boolean views) { this.views = views; } public boolean isFolders() { if (null != this.folders) { return this.folders; } ValueBinding _vb = getValueBinding("folders"); //$NON-NLS-1$ if (_vb != null) { Boolean val = (java.lang.Boolean) _vb.getValue(FacesContext.getCurrentInstance()); if (val != null) { return val; } } return true; } public void setFolders(boolean folders) { this.folders = folders; } @Override public void restoreState(FacesContext _context, Object _state) { Object _values[] = (Object[]) _state; super.restoreState(_context, _values[0]); databaseName = (String) _values[1]; filter = (String) _values[2]; var = (String) _values[3]; views = (Boolean) _values[4]; folders = (Boolean) _values[5]; } @Override public Object saveState(FacesContext _context) { Object _values[] = new Object[6]; _values[0] = super.saveState(_context); _values[1] = databaseName; _values[2] = filter; _values[3] = var; _values[4] = views; _values[5] = folders; return _values; } // ====================================================== // Tree implementation // ====================================================== @Override @SuppressWarnings("unchecked") // $NON-NLS-1$ public ITreeNode.NodeIterator iterateChildren(int start, int count) { try { Database db = DominoUtils.openDatabaseByName(getDatabaseName()); Vector<View> v = (Vector<View>) db.getViews(); // NTF begin sort addition -- this should really be a property on the component Object[] va = v.toArray(); Arrays.sort(va, new Comparator() { public int compare(Object arg0, Object arg1) { if (arg0 instanceof View && arg1 instanceof View) { try { return ((View) arg0).getName().compareTo(((View) arg1).getName()); } catch (NotesException ne) { // What should we really do here? return 0; } } else { return 0; } } }); Vector<View> vsort = new Vector<View>(); for (Object cv : va) { vsort.add((View) cv); } // (new QuickSort.JavaVector(v)).sort(); //NTF I'm REALLY wondering why this was commented out. What use is // the view list in NoteID order anyway? // return new ListIterator(v,start,count); //NTF old version that doesn't sort the view Vector first return new ListIterator(vsort, start, count); // NTF new version that uses the sorted Vector P.S: Vectors // suck! // NTF END sort addition. We'll see if priand keeps it around! :-) } catch (NotesException ex) { throw new FacesExceptionEx(ex, "Error while reading the list or views/folders"); // $NLX-ViewListTreeNode.Errorwhilereadingthelistorviewsfo-1$ } } private class ListIterator implements ITreeNode.NodeIterator { private Iterator<View> it; private boolean acceptViews; private boolean acceptFolders; private View current; private int count; private String filter; ListIterator(Vector<View> list, int start, int count) { this.it = list.iterator(); this.count = count; this.acceptViews = isViews(); this.acceptFolders = isFolders(); this.filter = getFilter(); // Skip the first... if (start > 0) { // todo... } moveToNext(); } public boolean hasNext() { return current != null; } public ITreeNode next() { ITreeNode res = new ViewNode(current); moveToNext(); return res; } private void moveToNext() { // If no more entries to retrieve, then stop! if (count == 0) { current = null; return; } // If there is a child list iterator, use it while (it.hasNext()) { current = it.next(); if (accept(current)) { return; } } // Ok, nothing then... current = null; } boolean accept(View view) { try { // Try on the view type if (!acceptFolders && view.isFolder()) { return false; } if (!acceptViews && !view.isFolder()) { return false; } // Else, use the selection if (StringUtil.isNotEmpty(filter)) { if (!view.getName().matches(filter)) { return false; } } } catch (NotesException ex) { } return true; } } private class ViewNode extends TreeNodeWrapper { private static final long serialVersionUID = 1L; private View view; ViewNode(View view) { super(ViewListTreeNode.this, getVar(), view); this.view = view; } @Override public int getType() { return NODE_LEAF; } @Override public String getLabel() { String s = super.getLabel(); if (StringUtil.isEmpty(s)) { try { s = view.getName(); if (StringUtil.isEmpty(s)) { s = "untitled"; // $NLS-ViewListTreeNode.untitled-1$ } } catch (NotesException ex) { } } return s; } @Override public ITreeNode.NodeIterator iterateChildren(int start, int count) { return null; } } }