diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxMultipleSearch.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxMultipleSearch.java new file mode 100644 index 000000000..439246bb8 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxMultipleSearch.java @@ -0,0 +1,275 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.common.components.bandboxsearch; + +import static org.navalplanner.web.I18nHelper._; + +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang.StringUtils; +import org.navalplanner.web.common.components.finders.IMultipleFiltersFinder; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.HtmlMacroComponent; +import org.zkoss.zk.ui.WrongValueException; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.InputEvent; +import org.zkoss.zul.Bandbox; +import org.zkoss.zul.ListModel; +import org.zkoss.zul.Listhead; +import org.zkoss.zul.Listheader; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.SimpleListModel; +import org.zkoss.zul.api.Listbox; + +/** + * @author Susana Montes Pedreira + */ + +@SuppressWarnings("serial") +public class BandboxMultipleSearch extends HtmlMacroComponent { + + private Listbox listbox; + + private Listhead listhead; + + private Bandbox bandbox; + + private String widthBandbox; + + private String widthListbox; + + private IMultipleFiltersFinder multipleFiltersFinder; + + private List selectedFilters = new ArrayList(); + + private String selectedFiltersText = new String(""); + + public void afterCompose() { + super.afterCompose(); + listbox = (Listbox) getFellowIfAny("listbox"); + listhead = (Listhead) listbox.getFellowIfAny("listhead"); + bandbox = (Bandbox) getFellowIfAny("bandbox"); + + if (multipleFiltersFinder != null) { + multipleFiltersFinder.init(); + listbox.setModel(new SimpleListModel(multipleFiltersFinder + .getMatching(""))); + listbox.setItemRenderer(multipleFiltersFinder.getItemRenderer()); + addHeaders(); + + /** + * Search for matching elements while typing on bandbox + */ + bandbox.addEventListener("onChanging", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + final String inputText = ((InputEvent) event).getValue(); + if ((inputText == null) || (inputText.isEmpty())) { + clear(); + } else { + String newFilterText = getNewFilterText(inputText); + if ((newFilterText != null) + && (newFilterText.length() > 2)) { + listbox.setModel(getSubModel(newFilterText)); + listbox.invalidate(); + } else { + clearListbox(); + } + } + } + }); + + /** + * Pick element from list when selecting + */ + listbox.addEventListener("onSelect", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + final Object object = getSelectedItem().getValue(); + addSelectedElement(object); + bandbox.close(); + clearListbox(); + } + }); + } + + updateWidth(); + } + + private String getNewFilterText(String inputText){ + String newFilterText = new String(""); + String[] filtersText = inputText.split(","); + newFilterText = getLastText(filtersText); + newFilterText = newFilterText.replace(" ", ""); + newFilterText = newFilterText.trim(); + return newFilterText; + } + + private String getLastText(String[] texts) { + Integer last = texts.length - 1; + if (texts.length > 0) { + return texts[last]; + } else { + return ""; + } + } + + private void clearSelectedElement() { + bandbox.setValue(""); + selectedFiltersText = ""; + selectedFilters.clear(); + } + + public void addSelectedElement(Object obj) { + if (obj != null) { + selectedFiltersText = selectedFiltersText + .concat(multipleFiltersFinder.objectToString(obj)); + bandbox.setValue(selectedFiltersText); + selectedFilters.add(obj); + } + } + + public List getSelectedElements() { + if (this.multipleFiltersFinder != null) { + if (!multipleFiltersFinder.isValidFormatText(selectedFilters, + bandbox.getValue())) { + throw new WrongValueException(bandbox, + _("format filters are not valid")); + } + } + return selectedFilters; + } + + /** + * Find {@link Label} which name or type start with prefix + * @param inputText + */ + @SuppressWarnings("unchecked") + private ListModel getSubModel(String inputText) { + List result = multipleFiltersFinder.getMatching(inputText); + return new SimpleListModel(result); + } + + /** + * Append headers to listbox header list + */ + @SuppressWarnings("unchecked") + public void addHeaders() { + clearHeaderIfNecessary(); + final String[] headers = multipleFiltersFinder.getHeaders(); + for (int i = 0; i < headers.length; i++) { + listhead.getChildren().add(new Listheader(headers[i])); + } + } + + private void clearHeaderIfNecessary() { + if (listhead.getChildren() != null) { + listhead.getChildren().clear(); + } + } + + private Listitem getSelectedItem() { + return (Listitem) listbox.getSelectedItems().iterator().next(); + } + + public void setDisabled(boolean disabled) { + bandbox.setDisabled(disabled); + } + + private Object getBean(String beanName) { + HttpServletRequest servletRequest = (HttpServletRequest) Executions + .getCurrent().getNativeRequest(); + ServletContext servletContext = servletRequest.getSession() + .getServletContext(); + WebApplicationContext webApplicationContext = WebApplicationContextUtils + .getWebApplicationContext(servletContext); + return webApplicationContext.getBean(beanName); + } + + public String getFinder() { + return multipleFiltersFinder.getClass().toString(); + } + + public void setFinder(String classname) { + multipleFiltersFinder = (IMultipleFiltersFinder) getBean(StringUtils + .uncapitalize(classname)); + } + + /** + * Clears {@link Bandbox} Fills bandbox list model, clear bandbox textbox, + * and set selected label to null + * @param bandbox + */ + public void clear() { + clearListbox(); + clearSelectedElement(); + } + + private void clearListbox() { + List list = new ArrayList(); + listbox.setModel(new SimpleListModel(list)); + listbox.invalidate(); + } + + public List asList(ListModel model) { + List result = new ArrayList(); + for (int i = 0; i < model.getSize(); i++) { + result.add(model.getElementAt(i)); + } + return result; + } + + public void setListboxEventListener(String event, EventListener listener) { + listbox.addEventListener(event, listener); + } + + public String getWidthBandbox() { + return widthBandbox; + } + + public void setWidthBandbox(String widthBandbox) { + this.widthBandbox = widthBandbox; + } + + public String getWidthListbox() { + return widthListbox; + } + + public void setWidthListbox(String widthListbox) { + this.widthListbox = widthListbox; + } + + private void updateWidth() { + if ((widthBandbox != null) && (!widthBandbox.isEmpty())) { + this.bandbox.setWidth(widthBandbox); + this.listbox.setWidth(widthListbox); + } + } +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxSearch.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxSearch.java index 635a55641..ef0a9aa21 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxSearch.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/bandboxsearch/BandboxSearch.java @@ -21,7 +21,9 @@ package org.navalplanner.web.common.components.bandboxsearch; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -57,6 +59,8 @@ public class BandboxSearch extends HtmlMacroComponent { private IBandboxFinder finder; + private static Map mapMatching = new HashMap(); + private String widthBandbox; private String widthListbox; diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/FilterPair.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/FilterPair.java new file mode 100644 index 000000000..dccd13927 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/FilterPair.java @@ -0,0 +1,66 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.common.components.finders; + +/** + * @author Susana Montes Pedreira + */ +public class FilterPair extends Object { + + private OrderFilterEnum type; + + private String pattern; + + private Object value; + + public FilterPair() { + } + + public FilterPair(OrderFilterEnum type, String pattern, Object value) { + this.type = type; + this.value = value; + this.pattern = pattern; + } + + public OrderFilterEnum getType() { + return type; + } + + public void setType(OrderFilterEnum type) { + this.type = type; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public String getPattern() { + return pattern; + } + + public void setPattern(String pattern) { + this.pattern = pattern; + } +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/IMultipleFiltersFinder.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/IMultipleFiltersFinder.java new file mode 100644 index 000000000..055eb6d63 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/IMultipleFiltersFinder.java @@ -0,0 +1,46 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.common.components.finders; + +import java.util.List; + +import org.zkoss.zul.ListitemRenderer; + +/** + * Contract for {@link MultipleFilterFinder}
+ * @author Susana Montes Pedreira + */ + +public interface IMultipleFiltersFinder { + + void init(); + + List getMatching(String filter); + + String objectToString(Object obj); + + boolean isValidFormatText(List filterValues, String value); + + String[] getHeaders(); + + ListitemRenderer getItemRenderer(); + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/MultipleFiltersFinder.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/MultipleFiltersFinder.java new file mode 100644 index 000000000..38ae3daec --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/common/components/finders/MultipleFiltersFinder.java @@ -0,0 +1,341 @@ +/* + * This file is part of ###PROJECT_NAME### + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.common.components.finders; + +import static org.navalplanner.web.I18nHelper._; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.navalplanner.business.externalcompanies.daos.IExternalCompanyDAO; +import org.navalplanner.business.externalcompanies.entities.ExternalCompany; +import org.navalplanner.business.labels.daos.ILabelDAO; +import org.navalplanner.business.labels.daos.ILabelTypeDAO; +import org.navalplanner.business.labels.entities.Label; +import org.navalplanner.business.labels.entities.LabelType; +import org.navalplanner.business.orders.daos.IOrderDAO; +import org.navalplanner.business.orders.entities.Order; +import org.navalplanner.business.orders.entities.OrderStatusEnum; +import org.navalplanner.business.qualityforms.entities.QualityForm; +import org.navalplanner.business.resources.daos.ICriterionDAO; +import org.navalplanner.business.resources.daos.ICriterionTypeDAO; +import org.navalplanner.business.resources.entities.Criterion; +import org.navalplanner.business.resources.entities.CriterionType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.zkoss.zul.Listcell; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.ListitemRenderer; + + +/** + * Implements all the methods needed to search the criterion to filter the + * orders. Provides multiples criterions to filter like {@link Criterion}, + * {@link Label}, {@link OrderStatusEnum},{@link ExternalCompany} object , or + * filter by order code or customer reference. + * @author Susana Montes Pedreira + */ +@Service +@Scope(BeanDefinition.SCOPE_SINGLETON) +public class MultipleFiltersFinder implements IMultipleFiltersFinder { + + @Autowired + private ICriterionTypeDAO criterionTypeDAO; + + @Autowired + private ILabelTypeDAO labelTypeDAO; + + @Autowired + private IExternalCompanyDAO externalCompanyDAO; + + @Autowired + private ICriterionDAO criterionDAO; + + @Autowired + private ILabelDAO labelDAO; + + @Autowired + private IOrderDAO orderDAO; + + private static final Map> mapCriterions = new HashMap>(); + + private static final Map> mapLabels = new HashMap>(); + + private static final List externalCompanies = new ArrayList(); + + private static final List customerReferences = new ArrayList(); + + private static OrderStatusEnum[] ordersStatusEnums; + + private static final List ordersCodes = new ArrayList(); + + private List listMatching = new ArrayList(); + + private final String headers[] = { _("Filter type"), _("Filter pattern") }; + + protected MultipleFiltersFinder() { + + } + + @Transactional(readOnly = true) + public void init() { + loadLabels(); + loadCriterions(); + loadExternalCompanies(); + loadOrdersStatusEnums(); + loadOrderCodesAndCustomerReferences(); + } + + private void loadCriterions() { + mapCriterions.clear(); + List criterionTypes = criterionTypeDAO + .getCriterionTypes(); + for (CriterionType criterionType : criterionTypes) { + List criterions = new ArrayList(criterionDAO + .findByType(criterionType)); + + mapCriterions.put(criterionType, criterions); + } + } + + private void loadLabels() { + mapLabels.clear(); + List labelTypes = labelTypeDAO.getAll(); + for (LabelType labelType : labelTypes) { + List