- New filter for ObjectLists which operates on a category system (either the

one used for the navigation or a secondary one). The filter can also be used 
  for implementing a search for tags (which are in fact categories).
- Some formating


git-svn-id: https://svn.libreccm.org/ccm/trunk@2325 8810af33-2d31-482b-a856-94f89814c4df
master
jensp 2013-09-28 17:05:01 +00:00
parent e209bd4b5e
commit bf25dc8dd2
5 changed files with 360 additions and 217 deletions

View File

@ -649,6 +649,7 @@ public class AuthoringKitWizard extends LayoutPanel implements Resettable {
private final Object m_key; private final Object m_key;
private Object m_nextKey; private Object m_nextKey;
public StepComponent(Object key) { public StepComponent(Object key) {
m_key = key; m_key = key;
} }

View File

@ -0,0 +1,144 @@
package com.arsdigita.navigation.ui.object;
import com.arsdigita.categorization.Category;
import com.arsdigita.categorization.CategoryCollection;
import com.arsdigita.domain.DomainObjectFactory;
import com.arsdigita.persistence.CompoundFilter;
import com.arsdigita.persistence.DataCollection;
import com.arsdigita.persistence.FilterFactory;
import com.arsdigita.persistence.SessionManager;
import com.arsdigita.xml.Element;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Jens Pelzetter <jens@jp-digital.de>
* @version $Id$
*/
public class CategoryFilter {
private final String label;
private final Category filterRootCat;
// private boolean descendCategories = true;
//private String value;
private final List<String> values = new ArrayList<String>();
public static CategoryFilter createCategoryFilter(final String label, final String categoryName) {
final DataCollection collection = SessionManager.getSession().retrieve(
Category.BASE_DATA_OBJECT_TYPE);
collection.addEqualsFilter(Category.NAME, categoryName);
if (collection.next()) {
final Category category = (Category) DomainObjectFactory.newInstance(
collection.getDataObject());
return new CategoryFilter(label, category);
} else {
throw new IllegalArgumentException(String.format(
"A category with the provided name '%s' does not exist", categoryName));
}
}
public CategoryFilter(final String label, final Category filterRootCat) {
this.label = label;
this.filterRootCat = filterRootCat;
}
// public boolean getDescendCategories() {
// return descendCategories;
// }
//
// public void setDescendCategories(final boolean descendCategories) {
// this.descendCategories = descendCategories;
// }
public void applyFilter(final DataCollection objects) {
// for(String value : values) {
// if ((value != null) && !value.isEmpty()) {
// if(descendCategories) {
// com.arsdigita.persistence.Filter filter = objects.addInSubqueryFilter("parent.id",
// "com.arsdigita.categorization.objectIDsInSubtree");
// filter.set("categoryID", value);
// objects.addFilter(filter);
// } else {
// objects.addEqualsFilter("parent.categories.id", value);
// }
// }
// }
if (!values.isEmpty()) {
// if (descendCategories) {
final FilterFactory filterFactory = objects.getFilterFactory();
final CompoundFilter compoundFilter = filterFactory.and();
for (String value : values) {
final com.arsdigita.persistence.Filter filter = filterFactory.in("parent.id",
"com.arsdigita.categorization.objectIDsInSubtree");
filter.set("categoryID", value);
compoundFilter.addFilter(filter);
}
objects.addFilter(compoundFilter);
// com.arsdigita.persistence.Filter filter = objects.addInSubqueryFilter("parent.id",
// "com.arsdigita.categorization.objectIDsInSubtree");
// filter.set("categoryID", values.get(0));
// } else {
// final com.arsdigita.persistence.Filter filter = objects.addFilter(
// "parent.categories.id IN :categories");
// filter.set("categories", values);
//objects.addEqualsFilter("parent.categories.id", values.get(0));
// final FilterFactory filterFactory = objects.getFilterFactory();
// final CompoundFilter compoundFilter = filterFactory.or();
// for (String value : values) {
// final com.arsdigita.persistence.Filter filter = filterFactory.equals(
// "parent.categories.id", value);
// compoundFilter.addFilter(filter);
// }
//
// objects.addFilter(compoundFilter);
// }
}
}
public Element getXml() {
final Element filter = new Element("filter");
filter.addAttribute("name", "categoryFilter");
filter.addAttribute("label", label);
final CategoryCollection categories = filterRootCat.getChildren();
categories.addOrder("name");
Category category;
while (categories.next()) {
category = categories.getCategory();
addCategoryToFilter(filter, category);
}
return filter;
}
private void addCategoryToFilter(final Element parent, final Category category) {
final Element elem = new Element("category");
elem.addAttribute("id", category.getID().toString());
//if ((value != null) && !value.isEmpty() && value.equals(category.getID().toString())) {
if ((values != null) && !values.isEmpty() && values.contains(category.getID().toString())) {
elem.addAttribute("selected", "selected");
}
elem.setText(category.getName());
parent.addContent(elem);
}
public void setValue(final String value) {
if ((value != null) && !value.isEmpty()) {
final String[] tokens = value.split(" ");
for (String token : tokens) {
values.add(token.trim());
}
}
}
}

View File

@ -90,15 +90,15 @@ public class CustomizableObjectList extends ComplexObjectList {
* *
*/ */
private final Map<String, Filter> filters = private final Map<String, Filter> filters =
new LinkedHashMap<String, Filter>(); new LinkedHashMap<String, Filter>();
//private CategoryFilter categoryFilter; private CategoryFilter categoryFilter;
/** /**
* The available sort fields. We use an {@link LinkedHashMap} here to * The available sort fields. We use an {@link LinkedHashMap} here to
* preserve the insertation order. * preserve the insertation order.
* *
*/ */
private final Map<String, String> sortFields = private final Map<String, String> sortFields =
new LinkedHashMap<String, String>(); new LinkedHashMap<String, String>();
/** /**
* Adds a new text filter to the list. * Adds a new text filter to the list.
@ -132,17 +132,17 @@ public class CustomizableObjectList extends ComplexObjectList {
* *
*/ */
public CompareFilter addCompareFilter(final String property, public CompareFilter addCompareFilter(final String property,
final String label, final String label,
final boolean allOption, final boolean allOption,
final boolean allOptionIsDefault, final boolean allOptionIsDefault,
final boolean propertyIsNumeric) { final boolean propertyIsNumeric) {
CompareFilter filter; CompareFilter filter;
filter = new CompareFilter(property, filter = new CompareFilter(property,
label, label,
allOption, allOption,
allOptionIsDefault, allOptionIsDefault,
propertyIsNumeric); propertyIsNumeric);
filters.put(label, filter); filters.put(label, filter);
return filter; return filter;
@ -162,29 +162,30 @@ public class CustomizableObjectList extends ComplexObjectList {
* boolean, boolean, boolean) * boolean, boolean, boolean)
*/ */
public void addSelectFilter(final String property, public void addSelectFilter(final String property,
final String label, final String label,
final boolean reverseOptions, final boolean reverseOptions,
final boolean allOption, final boolean allOption,
final boolean allOptionIsDefault, final boolean allOptionIsDefault,
final boolean propertyIsNumeric) { final boolean propertyIsNumeric) {
SelectFilter filter; SelectFilter filter;
filter = new SelectFilter(property, filter = new SelectFilter(property,
label, label,
this, this,
reverseOptions, reverseOptions,
allOption, allOption,
allOptionIsDefault, allOptionIsDefault,
propertyIsNumeric); propertyIsNumeric);
filters.put(label, filter); filters.put(label, filter);
} }
// public CategoryFilter addCategoryFilter(final String label, public CategoryFilter addCategoryFilter(final String label,
// final String rootCategory) { final String rootCategory) {
// categoryFilter = CategoryFilter.createCategoryFilter(label, rootCategory); categoryFilter = CategoryFilter.createCategoryFilter(label, rootCategory);
//
// return categoryFilter; return categoryFilter;
// } }
/** /**
* Add a sort field option. * Add a sort field option.
* *
@ -221,7 +222,7 @@ public class CustomizableObjectList extends ComplexObjectList {
*/ */
@Override @Override
protected DataCollection getObjects(final HttpServletRequest request, protected DataCollection getObjects(final HttpServletRequest request,
final HttpServletResponse response) { final HttpServletResponse response) {
//Set filters (using the SQL) //Set filters (using the SQL)
// final StringBuilder sqlFilters = new StringBuilder(); // final StringBuilder sqlFilters = new StringBuilder();
// for (Map.Entry<String, Filter> filterEntry : filters.entrySet()) { // for (Map.Entry<String, Filter> filterEntry : filters.entrySet()) {
@ -248,9 +249,9 @@ public class CustomizableObjectList extends ComplexObjectList {
final DataCollection objects = super.getObjects(request, response); final DataCollection objects = super.getObjects(request, response);
// if ((objects != null) && (categoryFilter != null)) { if ((objects != null) && (categoryFilter != null)) {
// categoryFilter.applyFilter(objects); categoryFilter.applyFilter(objects);
// } }
return objects; return objects;
} }
@ -259,7 +260,7 @@ public class CustomizableObjectList extends ComplexObjectList {
final StringBuilder sqlFilters = new StringBuilder(); final StringBuilder sqlFilters = new StringBuilder();
for (Map.Entry<String, Filter> filterEntry : filters.entrySet()) { for (Map.Entry<String, Filter> filterEntry : filters.entrySet()) {
if ((filterEntry.getValue().getFilter() == null) if ((filterEntry.getValue().getFilter() == null)
|| (filterEntry.getValue().getFilter().isEmpty())) { || (filterEntry.getValue().getFilter().isEmpty())) {
continue; continue;
} }
@ -291,7 +292,7 @@ public class CustomizableObjectList extends ComplexObjectList {
*/ */
@Override @Override
public Element generateXML(final HttpServletRequest request, public Element generateXML(final HttpServletRequest request,
final HttpServletResponse response) { final HttpServletResponse response) {
//Some stuff for the list (copied from ComplexObjectList) //Some stuff for the list (copied from ComplexObjectList)
final Element content = Navigation.newElement("customizableObjectList"); final Element content = Navigation.newElement("customizableObjectList");
@ -327,15 +328,15 @@ public class CustomizableObjectList extends ComplexObjectList {
filterEntry.getValue().setValue(value); filterEntry.getValue().setValue(value);
} }
} }
// if (categoryFilter != null) { if (categoryFilter != null) {
// final String value = Globalization.decodeParameter(request, "categoryFilter"); final String value = Globalization.decodeParameter(request, "categoryFilter");
//
// if ((value != null) && !value.isEmpty()) {
// categoryFilter.setValue(value);
// }
// }
if (!filters.isEmpty()) { if ((value != null) && !value.isEmpty()) {
categoryFilter.setValue(value);
}
}
if (!filters.isEmpty() || (categoryFilter != null)) {
final Element controls = content.newChildElement("filterControls"); final Element controls = content.newChildElement("filterControls");
controls.addAttribute("customName", m_customName); controls.addAttribute("customName", m_customName);
@ -344,9 +345,9 @@ public class CustomizableObjectList extends ComplexObjectList {
for (Map.Entry<String, Filter> filterEntry : filters.entrySet()) { for (Map.Entry<String, Filter> filterEntry : filters.entrySet()) {
filterElems.addContent(filterEntry.getValue().getXml()); filterElems.addContent(filterEntry.getValue().getXml());
} }
// if (categoryFilter != null) { if (categoryFilter != null) {
// filterElems.addContent(categoryFilter.getXml()); filterElems.addContent(categoryFilter.getXml());
// } }
if (!sortFields.isEmpty()) { if (!sortFields.isEmpty()) {
//Look for a sort parameter. If one is found, use one to sort the data //Look for a sort parameter. If one is found, use one to sort the data
@ -371,4 +372,5 @@ public class CustomizableObjectList extends ComplexObjectList {
return content; return content;
} }
} }

View File

@ -12,7 +12,6 @@
* rights and limitations under the License. * rights and limitations under the License.
* *
*/ */
package com.arsdigita.portalworkspace.ui.admin; package com.arsdigita.portalworkspace.ui.admin;
import com.arsdigita.bebop.Form; import com.arsdigita.bebop.Form;
@ -27,8 +26,6 @@ import com.arsdigita.portalworkspace.WorkspacePage;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
/** /**
* Entry page for PortalWorkspace administration. * Entry page for PortalWorkspace administration.
* *
@ -41,95 +38,97 @@ import org.apache.log4j.Logger;
*/ */
public class AdminPane extends SimpleContainer { public class AdminPane extends SimpleContainer {
private static final Logger s_log = Logger.getLogger(AdminPane.class); private static final Logger s_log = Logger.getLogger(AdminPane.class);
private ApplicationSelectionModel m_app;
private ApplicationSelectionModel m_app; private CategoryComponent m_catComponent;
private DeleteApplicationComponent m_deleteApplicationComponent;
private CategoryComponent m_catComponent; /**
private DeleteApplicationComponent m_deleteApplicationComponent;
/**
* *
*/ */
public AdminPane() { public AdminPane() {
setTag("portal:admin"); setTag("portal:admin");
setNamespace(WorkspacePage.PORTAL_XML_NS); setNamespace(WorkspacePage.PORTAL_XML_NS);
m_app = new ApplicationSelectionModel("application", true);
m_app = new ApplicationSelectionModel("application", true);
/* Add component to select a Navigation Category for this portal */ /* Add component to select a Navigation Category for this portal */
m_catComponent = new CategoryComponent(m_app); m_catComponent = new CategoryComponent(m_app);
m_catComponent.setIdAttr("categoryComponent"); m_catComponent.setIdAttr("categoryComponent");
add(m_catComponent); add(m_catComponent);
/* Add component "Extrem Action": Delete this portal */ /* Add component "Extrem Action": Delete this portal */
m_deleteApplicationComponent = new DeleteApplicationComponent(m_app, m_deleteApplicationComponent = new DeleteApplicationComponent(m_app,
m_app.getDefaultApplication().getApplicationType()); m_app.getDefaultApplication().
m_deleteApplicationComponent.setIdAttr("deleteComponent"); getApplicationType());
add(m_deleteApplicationComponent); m_deleteApplicationComponent.setIdAttr("deleteComponent");
add(m_deleteApplicationComponent);
/* Add component to manage Members group members for this portal */ /* Add component to manage Members group members for this portal */
GroupMemberDisplay members = new GroupMemberDisplay() { GroupMemberDisplay members = new GroupMemberDisplay() {
public Group getGroup(PageState state) { public Group getGroup(PageState state) {
Workspace workspace = (Workspace) Kernel.getContext() Workspace workspace = (Workspace) Kernel.getContext()
.getResource(); .getResource();
return (Group) workspace.getParty(); return (Group) workspace.getParty();
} }
};
members.setIdAttr("memberDisplay");
add(members);
Form form = new Form("userPicker", new SimpleContainer( };
"portal:memberPicker", WorkspacePage.PORTAL_XML_NS)); members.setIdAttr("memberDisplay");
form.add(new GroupMemberPicker() { add(members);
public Group getGroup(PageState state) {
Workspace workspace = (Workspace) Kernel.getContext() Form form = new Form("userPicker", new SimpleContainer(
.getResource(); "portal:memberPicker", WorkspacePage.PORTAL_XML_NS));
return (Group) workspace.getParty(); form.add(new GroupMemberPicker() {
} public Group getGroup(PageState state) {
}); Workspace workspace = (Workspace) Kernel.getContext()
form.setIdAttr("memberUserPicker"); .getResource();
add(form); return (Group) workspace.getParty();
}
});
form.setIdAttr("memberUserPicker");
add(form);
/* Add component to manage Admins group members for this portal */ /* Add component to manage Admins group members for this portal */
GroupMemberDisplay admins = new GroupMemberDisplay() { GroupMemberDisplay admins = new GroupMemberDisplay() {
public Group getGroup(PageState state) { public Group getGroup(PageState state) {
Workspace workspace = (Workspace) Kernel.getContext() Workspace workspace = (Workspace) Kernel.getContext()
.getResource(); .getResource();
Group members = ((Group) workspace.getParty()); Group members = ((Group) workspace.getParty());
Role admins = members.getRole("Administrators"); Role admins = members.getRole("Administrators");
if (admins == null) { if (admins == null) {
admins = members.createRole("Administrators"); admins = members.createRole("Administrators");
admins.save(); admins.save();
} }
return admins.getGroup(); return admins.getGroup();
} }
};
admins.setIdAttr("adminDisplay"); };
add(admins); admins.setIdAttr("adminDisplay");
add(admins);
Form adminForm = new Form("adminPicker", new SimpleContainer(
"portal:adminPicker", WorkspacePage.PORTAL_XML_NS));
adminForm.add(new GroupMemberPicker() {
public Group getGroup(PageState state) {
Workspace workspace = (Workspace) Kernel.getContext()
.getResource();
Group members = ((Group) workspace.getParty());
Role admins = members.getRole("Administrators");
if (admins == null) {
admins = members.createRole("Administrators");
admins.save();
}
return admins.getGroup();
}
});
adminForm.setIdAttr("adminUserPicker");
add(adminForm);
}
Form adminForm = new Form("adminPicker", new SimpleContainer(
"portal:adminPicker", WorkspacePage.PORTAL_XML_NS));
adminForm.add(new GroupMemberPicker() {
public Group getGroup(PageState state) {
Workspace workspace = (Workspace) Kernel.getContext()
.getResource();
Group members = ((Group) workspace.getParty());
Role admins = members.getRole("Administrators");
if (admins == null) {
admins = members.createRole("Administrators");
admins.save();
}
return admins.getGroup();
}
});
adminForm.setIdAttr("adminUserPicker");
add(adminForm);
}
} }

View File

@ -15,7 +15,6 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
package com.arsdigita.portalworkspace.ui.admin; package com.arsdigita.portalworkspace.ui.admin;
import com.arsdigita.portalworkspace.ui.sitemap.ApplicationSelectionModel; import com.arsdigita.portalworkspace.ui.sitemap.ApplicationSelectionModel;
@ -50,126 +49,124 @@ import com.arsdigita.web.Web;
*/ */
public class CategoryComponent extends SimpleContainer { public class CategoryComponent extends SimpleContainer {
private static final Logger s_log = Logger private static final Logger s_log = Logger
.getLogger(CategoryComponent.class); .getLogger(CategoryComponent.class);
private ACSObjectSelectionModel m_catModel;
private CategoryTree m_tree;
private ApplicationSelectionModel m_appModel;
private Label m_error;
private static final Application m_app = Web.getContext().getApplication();
private static final Category m_root = Category.getRootForObject(m_app);
private ACSObjectSelectionModel m_catModel; /**
private CategoryTree m_tree;
private ApplicationSelectionModel m_appModel;
private Label m_error;
private static final Application m_app = Web.getContext().getApplication();
private static final Category m_root = Category.getRootForObject(m_app);
/**
* *
* @param appModel * @param appModel
*/ */
public CategoryComponent(ApplicationSelectionModel appModel) { public CategoryComponent(ApplicationSelectionModel appModel) {
// this model means that the server needs a restart // this model means that the server needs a restart
// if you want to map a category to this personal portal // if you want to map a category to this personal portal
// AND vice versa - if you remove a domain mapping you need to // AND vice versa - if you remove a domain mapping you need to
// restart the server otherwise you will get an exception next time // restart the server otherwise you will get an exception next time
// this Component is viewed. // this Component is viewed.
if (m_root != null) { if (m_root != null) {
setNamespace(WorkspacePage.PORTAL_XML_NS); setNamespace(WorkspacePage.PORTAL_XML_NS);
setTag("portal:categoryPanel"); setTag("portal:categoryPanel");
m_appModel = appModel; m_appModel = appModel;
m_catModel = new ACSObjectSelectionModel("category"); m_catModel = new ACSObjectSelectionModel("category");
m_tree = new CategoryTree(m_catModel); m_tree = new CategoryTree(m_catModel);
add(m_tree); add(m_tree);
add(new CategoryTable(appModel, m_catModel)); add(new CategoryTable(appModel, m_catModel));
m_error = new Label(""); m_error = new Label("");
add(m_error); add(m_error);
} }
} }
/** /**
* *
*/ */
private class CategoryTree extends Tree { private class CategoryTree extends Tree {
public CategoryTree(ACSObjectSelectionModel categoryModel) {
super(new SectionTreeModelBuilder());
setSelectionModel(categoryModel);
addActionListener(new CategoryTreeActionListener(categoryModel));
}
} public CategoryTree(ACSObjectSelectionModel categoryModel) {
super(new SectionTreeModelBuilder());
setSelectionModel(categoryModel);
addActionListener(new CategoryTreeActionListener(categoryModel));
}
/** }
/**
* *
*/ */
private class CategoryTreeActionListener implements ActionListener { private class CategoryTreeActionListener implements ActionListener {
private ACSObjectSelectionModel m_catModel;
public CategoryTreeActionListener(ACSObjectSelectionModel catModel) { private ACSObjectSelectionModel m_catModel;
m_catModel = catModel;
}
public void actionPerformed(ActionEvent event) { public CategoryTreeActionListener(ACSObjectSelectionModel catModel) {
PageState state = event.getPageState(); m_catModel = catModel;
// categorize the Application }
s_log.debug("action performed");
if (m_catModel.isSelected(state)) {
Category category = (Category) m_catModel
.getSelectedObject(state);
// Make sure that other workspaces aren't already categorized public void actionPerformed(ActionEvent event) {
DataCollection workspaces = SessionManager.getSession() PageState state = event.getPageState();
.retrieve(Workspace.BASE_DATA_OBJECT_TYPE); // categorize the Application
s_log.debug("action performed");
if (m_catModel.isSelected(state)) {
Category category = (Category) m_catModel
.getSelectedObject(state);
Filter f = workspaces.addInSubqueryFilter("id", // Make sure that other workspaces aren't already categorized
"com.arsdigita.categorization.immediateChildObjectIDs"); DataCollection workspaces = SessionManager.getSession()
f.set("categoryID", category.getID().toString()); .retrieve(Workspace.BASE_DATA_OBJECT_TYPE);
if (workspaces.isEmpty()) { Filter f = workspaces.addInSubqueryFilter("id",
s_log.debug("About to categorize"); "com.arsdigita.categorization.immediateChildObjectIDs");
f.set("categoryID", category.getID().toString());
Workspace workspace = (Workspace) m_appModel if (workspaces.isEmpty()) {
.getSelectedObject(state); s_log.debug("About to categorize");
category.addChild(workspace);
category.save();
} else {
// print an error
while (workspaces.next()) {
Workspace wk = (Workspace) DomainObjectFactory
.newInstance(workspaces.getDataObject());
m_error.setLabel(
"This category already has a workspace "
+ wk.getTitle(), state);
}
}
}
}
}
/** Workspace workspace = (Workspace) m_appModel
* A TreeModelBuilder that loads the tree from the current category .getSelectedObject(state);
*/ category.addChild(workspace);
private static class SectionTreeModelBuilder extends LockableImpl implements category.save();
TreeModelBuilder { } else {
// print an error
while (workspaces.next()) {
Workspace wk = (Workspace) DomainObjectFactory
.newInstance(workspaces.getDataObject());
m_error.setLabel(
"This category already has a workspace "
+ wk.getTitle(), state);
}
}
}
}
public SectionTreeModelBuilder() { }
super();
}
public TreeModel makeModel(Tree t, PageState s) { /**
Application app = Web.getContext().getApplication(); * A TreeModelBuilder that loads the tree from the current category
Category root = null; */
while (app != null && root == null) { private static class SectionTreeModelBuilder extends LockableImpl implements
root = Category.getRootForObject(app); TreeModelBuilder {
app = (Application) app.getParentResource();
} public SectionTreeModelBuilder() {
Assert.exists(root, Category.class); super();
return new CategoryTreeModelLite(root); }
}
} public TreeModel makeModel(Tree t, PageState s) {
Application app = Web.getContext().getApplication();
Category root = null;
while (app != null && root == null) {
root = Category.getRootForObject(app);
app = (Application) app.getParentResource();
}
Assert.exists(root, Category.class);
return new CategoryTreeModelLite(root);
}
}
} }