Package org.geoserver.gwc.web.layer

Source Code of org.geoserver.gwc.web.layer.ParameterFilterEditor$ParameterListValidator

/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/

package org.geoserver.gwc.web.layer;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.behavior.SimpleAttributeModifier;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.FormComponentPanel;
import org.apache.wicket.markup.html.form.IChoiceRenderer;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.IValidator;
import org.apache.wicket.validation.ValidationError;
import org.geoserver.catalog.CatalogInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.gwc.GWC;
import org.geoserver.gwc.layer.StyleParameterFilter;
import org.geoserver.gwc.web.GWCIconFactory;
import org.geoserver.web.wicket.GeoServerAjaxFormLink;
import org.geoserver.web.wicket.Icon;
import org.geoserver.web.wicket.ImageAjaxLink;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geotools.util.logging.Logging;
import org.geowebcache.filter.parameters.FloatParameterFilter;
import org.geowebcache.filter.parameters.ParameterFilter;
import org.geowebcache.filter.parameters.RegexParameterFilter;
import org.geowebcache.filter.parameters.StringParameterFilter;

class ParameterFilterEditor extends FormComponentPanel<Set<ParameterFilter>> {

    private static final Logger LOGGER = Logging.getLogger(ParameterFilterEditor.class);

    private static final long serialVersionUID = 5098470663723800345L;
   
    private static final List<String> COMMON_KEYS = Arrays.asList(
            "ENV",
            "FORMAT_OPTIONS",
            "ANGLE",
            "BGCOLOR",
            "BUFFER",
            "CQL_FILTER",
            "ELEVATION",
            "FEATUREID",
            "FILTER",
            "PALETTE",
            "STARTINDEX",
            "MAXFEATURES",
            "TIME",
            "VIEWPARAMS",
            "FEATUREVERSION");

    private final WebMarkupContainer table;

    private final ListView<ParameterFilter> filters;

    private final ParameterListValidator validator;
   
    private final DropDownChoice<Class<? extends ParameterFilter>> availableFilterTypes;
    private final TextField<String> newFilterKey;
   
    private class ParameterListValidator implements IValidator<Set<ParameterFilter>> {

        private static final long serialVersionUID = 1L;

        private boolean validate;

        public ParameterListValidator() {
            this.setEnabled(true);
        }

        @Override
        public void validate(IValidatable<Set<ParameterFilter>> validatable) {
            if (!validate) {
                return;
            }
            Set<ParameterFilter> paramFilters = validatable.getValue();
            if (paramFilters == null) {
                return;
            }

            Set<String> keys = new TreeSet<String>();
            for (ParameterFilter filter : paramFilters) {
                // TODO Validate
                final String key = filter.getKey();

                if (key == null) {
                    throw new IllegalStateException("ParameterFilter key is null");
                } else {
                    if (keys.contains(key)) {
                        error(validatable, "ParameterFilterEditor.validation.duplicateKey");
                        return;
                    } else {
                        keys.add(key);
                    }
                }
                   

            }
        }

        private void error(IValidatable<Set<ParameterFilter>> validatable, final String resourceKey,
                final String... params) {

            ValidationError error = new ValidationError();
            String message;
            if (params == null) {
                message = new ResourceModel(resourceKey).getObject();
            } else {
                message = new ParamResourceModel(resourceKey, ParameterFilterEditor.this,
                        (Object[]) params).getObject();
            }
            error.setMessage(message);
            validatable.error(error);
        }

        public void setEnabled(boolean validate) {
            this.validate = validate;
        }
    }

    public ParameterFilterEditor(final String id, final IModel<Set<ParameterFilter>> model, final IModel<? extends CatalogInfo> layerModel) {
        super(id, model);
        add(validator = new ParameterListValidator());

        // container for ajax updates
        final WebMarkupContainer container = new WebMarkupContainer("container");
        container.setOutputMarkupId(true);
        add(container);

        // the link list
        table = new WebMarkupContainer("table");
        table.setOutputMarkupId(true);

        container.add(table);

        filters = new ListView<ParameterFilter>("parameterFilters", new ArrayList<ParameterFilter>(
                model.getObject())) {

            private static final long serialVersionUID = 1L;

            @Override
            protected void onBeforeRender() {
                super.onBeforeRender();
            }

            @Override
            protected void populateItem(final ListItem<ParameterFilter> item) {
                // odd/even style
                final int index = item.getIndex();
                item.add(new SimpleAttributeModifier("class", index % 2 == 0 ? "even" : "odd"));

                //Create form
                final Label keyLabel;
                keyLabel = new Label("key", new PropertyModel<String>(item.getModel(),"key"));
                item.add(keyLabel);
               
                final Component subForm = getSubform("subform", item.getModel());
                //final Component subForm = new Label("subform", "Blah");
                item.add(subForm);
               
                final Component removeLink;

                removeLink = new ImageAjaxLink("removeLink", GWCIconFactory.DELETE_ICON) {
                    private static final long serialVersionUID = 1L;

                    @Override
                    protected void onClick(AjaxRequestTarget target) {
                        List<ParameterFilter> list;
                        list = new ArrayList<ParameterFilter>(filters.getModelObject());
                        final ParameterFilter filter = (ParameterFilter) getDefaultModelObject();

                        list.remove(filter);
                        filters.setModelObject(list);
                        item.remove();

                        target.addComponent(container);
                    }
                };
                removeLink.setDefaultModel(item.getModel());
                removeLink.add(new AttributeModifier("title", true, new ResourceModel(
                        "ParameterFilterEditor.removeLink")));
                item.add(removeLink);
            }
        };

        filters.setOutputMarkupId(true);
        // this is necessary to avoid loosing item contents on edit/validation checks
        filters.setReuseItems(true);
        table.add(filters);

        List<String> parameterKeys = new ArrayList<String>(GWC.get().getGridSetBroker().getNames());
        for (ParameterFilter filter : model.getObject()) {
            parameterKeys.remove(filter.getKey());
        }
        Collections.sort(parameterKeys);
       
        GeoServerAjaxFormLink addStyleFilterLink = new GeoServerAjaxFormLink("addStyleFilter") {
            private static final long serialVersionUID = 1L;

            @Override
            protected void onClick(AjaxRequestTarget target, Form form) {
                StyleParameterFilter newFilter = new StyleParameterFilter();
                newFilter.setLayer((LayerInfo)layerModel.getObject());
               
                addFilter(newFilter);

                target.addComponent(container);
            }
        };
        addStyleFilterLink.add(new Icon("addIcon", GWCIconFactory.ADD_ICON));
        add(addStyleFilterLink);
       
        // FIXME: make this extensible so new kinds of filter can be supported by
        ArrayList<Class<? extends ParameterFilter>> filterTypes =
                new ArrayList<Class<? extends ParameterFilter>>();
        filterTypes.add(StringParameterFilter.class);
        filterTypes.add(FloatParameterFilter.class);
        filterTypes.add(RegexParameterFilter.class);
       
       
        availableFilterTypes = new DropDownChoice<Class<? extends ParameterFilter>>
            (       "availableFilterTypes",
                    new Model<Class<? extends ParameterFilter>>(),
                    new Model<ArrayList<Class<? extends ParameterFilter>>>(filterTypes),
                    new IChoiceRenderer<Class<? extends ParameterFilter>>() {

                        /** serialVersionUID */
                        private static final long serialVersionUID = 1L;

                        @Override
                        public Object getDisplayValue(
                                Class<? extends ParameterFilter> object) {
                            String resource = "ParameterFilterEditor.filtername."
                                    +object.getCanonicalName();
                            try {
                                // Try to look up a localized name for the class
                                return getLocalizer().getString(resource,
                                        ParameterFilterEditor.this);
                            } catch (MissingResourceException ex) {
                                // Use the simple name as a backup
                                if(LOGGER.isLoggable(Level.CONFIG))
                                    LOGGER.log(Level.CONFIG, "Could not find localization resource"+
                                " for ParameterFilter subclass "+object.getCanonicalName());
                               
                                return object.getSimpleName();
                            }
                        }

                        @Override
                        public String getIdValue(
                                Class<? extends ParameterFilter> object,
                                int index) {
                            return Integer.toString(index);
                        }
               
            });
        availableFilterTypes.setOutputMarkupId(true);
        add(availableFilterTypes);
       
        newFilterKey = new TextField<String>("newFilterKey", Model.of(""));
        add(newFilterKey);
       
        // TODO update this to eliminate keys that are in use
        final RepeatingView commonKeys = new RepeatingView("commonKeys");
        for(String key: COMMON_KEYS) {
            commonKeys.add(new Label(commonKeys.newChildId(), key));
        }
        add(commonKeys);
       
        GeoServerAjaxFormLink addFilterLink = new GeoServerAjaxFormLink("addFilter") {
            private static final long serialVersionUID = 1L;

            @Override
            protected void onClick(AjaxRequestTarget target, Form form) {
                availableFilterTypes.processInput();
                newFilterKey.processInput();
                String key = newFilterKey.getModelObject();
                if(key == null || key.isEmpty()){
                    ParamResourceModel rm = new ParamResourceModel("ParameterFilterEditor.nonEmptyFilter", null, "");
                    error(rm.getString());
                }else{
                    Class<? extends ParameterFilter> type = availableFilterTypes.getModelObject();

                    try {
                        ParameterFilter newFilter = type.getConstructor().newInstance();
                        newFilter.setKey(key);
                        addFilter(newFilter);
                        newFilterKey.setModel(Model.of("")); // Reset the key field
                    } catch (NoSuchMethodException ex) {
                        LOGGER.log(Level.WARNING, "No Default Constructor for "+type ,ex);
                    } catch (InvocationTargetException ex) {
                        LOGGER.log(Level.WARNING, "Could not execute default Constructor for "+type ,ex);
                    } catch (SecurityException ex) {
                        LOGGER.log(Level.WARNING, "Could not execute default Constructor for "+type ,ex);
                    } catch (InstantiationException ex) {
                        LOGGER.log(Level.WARNING, "Could not execute default Constructor for "+type ,ex);
                    } catch (IllegalAccessException ex) {
                        LOGGER.log(Level.WARNING, "Could not execute default Constructor for "+type ,ex);
                    }
                }
                target.addComponent(container);
            }
        };
        addFilterLink.add(new Icon("addIcon", GWCIconFactory.ADD_ICON));
        add(addFilterLink);
    }

    /**
     * Returns an appropriate subform for the given ParameterFilter model
     * @param model
     * @return
     */
    @SuppressWarnings("unchecked")
    private Component getSubform(String id, IModel<? extends ParameterFilter> model){
       
        if (model.getObject() instanceof RegexParameterFilter) {
            return new RegexParameterFilterSubform(id, (IModel<RegexParameterFilter>) model);
        }
        if (model.getObject() instanceof StyleParameterFilter) {
            return new StyleParameterFilterSubform(id, (IModel<StyleParameterFilter>) model);
        }
        if (model.getObject() instanceof StringParameterFilter) {
            return new StringParameterFilterSubform(id, (IModel<StringParameterFilter>) model);
        }
        if (model.getObject() instanceof FloatParameterFilter) {
            return new FloatParameterFilterSubform(id, (IModel<FloatParameterFilter>) model);
        }
        return new DefaultParameterFilterSubform(id, (IModel<ParameterFilter>) model);
    }
   
    @Override
    protected void convertInput() {
        filters.visitChildren(new Component.IVisitor<Component>() {

            @Override
            public Object component(Component component) {
                if (component instanceof FormComponent) {
                    FormComponent<?> formComponent = (FormComponent<?>) component;
                    formComponent.processInput();
                }
                return Component.IVisitor.CONTINUE_TRAVERSAL;
            }
        });
        List<ParameterFilter> info = filters.getModelObject();
        HashSet<ParameterFilter> convertedInput = new HashSet<ParameterFilter>(info);
        setConvertedInput(convertedInput);
    }

    private boolean hasFilter(String key) {
        for(ParameterFilter existing: filters.getModelObject()) {
            if(existing.getKey().equalsIgnoreCase(key)) return true;
        }
        return false;
    }
   
    private boolean addFilter(ParameterFilter filter) {
        if(hasFilter(filter.getKey())) return false;

        filters.getModelObject().add(filter);
        return true;
    }
   
    /**
     */
    @Override
    protected void onBeforeRender() {
        super.onBeforeRender();
    }

    public void setValidating(final boolean validate) {
        validator.setEnabled(validate);
    }

}
TOP

Related Classes of org.geoserver.gwc.web.layer.ParameterFilterEditor$ParameterListValidator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.