Package org.geoserver.gwc.web.layer

Source Code of org.geoserver.gwc.web.layer.GeoServerTileLayerEditor

/* (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 static com.google.common.base.Preconditions.checkArgument;
import static org.geoserver.gwc.GWC.tileLayerName;

import java.util.Arrays;
import java.util.List;
import java.util.Set;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Check;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.CheckGroup;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.FormComponent;
import org.apache.wicket.markup.html.form.FormComponentPanel;
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.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.model.ResourceModel;
import org.geoserver.catalog.CatalogInfo;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.MetadataMap;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.impl.ModificationProxy;
import org.geoserver.gwc.GWC;
import org.geoserver.gwc.layer.CatalogLayerEventListener;
import org.geoserver.gwc.layer.GeoServerTileLayer;
import org.geoserver.gwc.layer.GeoServerTileLayerInfo;
import org.geoserver.web.wicket.GeoServerDialog;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geowebcache.config.XMLGridSubset;
import org.geowebcache.diskquota.storage.Quota;
import org.geowebcache.filter.parameters.ParameterFilter;
import org.geowebcache.grid.GridSetBroker;
import org.geowebcache.layer.TileLayer;

import com.google.common.base.Preconditions;

/**
* Edit panel for a {@link GeoServerTileLayerInfo} (used to edit caching options for both
* {@link LayerInfo} and {@link LayerGroupInfo}.
* <p>
* If a tile layer existed for the given layer or layer group and the "create a cached layer"
* checkbox is unchecked, then the metadata properties defining the cached layers will be removed
* from the layer/group {@link MetadataMap}. Once the save button is pressed on the enclosing page,
* the {@link CatalogLayerEventListener} will caught the modification to the layer or layer group
* and delete the cache for the layer.
* </p>
*
* @author groldan
*
* @see GridSubsetsEditor
* @see LayerCacheOptionsTabPanel
* @see LayerGroupCacheOptionsPanel
*/
class GeoServerTileLayerEditor extends FormComponentPanel<GeoServerTileLayerInfo> {

    private static final long serialVersionUID = 7870938096047218989L;

    /**
     * Flag to indicate whether a cached layer initially existed for the given layer/group info so
     * that the cache for the layer is deleted at {@link #convertInput()}
     */
    private final boolean cachedLayerExistedInitially;

    /**
     * the confirm removal of existing tile layer and its associated cache dialog
     */
    private final GeoServerDialog confirmRemovalDialog;

    /**
     * Whether to create a {@link TileLayer} for this {@link LayerInfo} or {@link LayerGroupInfo}
     */
    private final FormComponent<Boolean> createLayer;

    /**
     * Whether the cached layer is enabled (like in {@link TileLayer#isEnabled()}
     */
    private final FormComponent<Boolean> enabled;

    /**
     * Container for {@link #configs}
     */
    private final WebMarkupContainer container;

    /**
     * Container for everything but {@link #createLayer}
     */
    private final WebMarkupContainer configs;

    private final FormComponent<Integer> metaTilingX;

    private final FormComponent<Integer> metaTilingY;

    private final FormComponent<Integer> gutter;

    private final CheckGroup<String> cacheFormats;
   
    private final FormComponent<Integer> expireCache;
   
    private final FormComponent<Integer> expireClients;

    private final GridSubsetsEditor gridSubsets;
    private final ParameterFilterEditor parameterFilters;

    private final String originalLayerName;

    private IModel<? extends CatalogInfo> layerModel;

    /**
     * @param id
     * @param layerModel
     * @param tileLayerModel must be a {@link GeoServerTileLayerInfoModel}
     */
    public GeoServerTileLayerEditor(final String id,
            final IModel<? extends CatalogInfo> layerModel,
            final IModel<GeoServerTileLayerInfo> tileLayerModel) {
        super(id);
        checkArgument(tileLayerModel instanceof GeoServerTileLayerInfoModel);
        this.layerModel = layerModel;
        setModel(tileLayerModel);

        final GWC mediator = GWC.get();
        final IModel<String> createTileLayerLabelModel;

        final CatalogInfo info = layerModel.getObject();
        final GeoServerTileLayerInfo tileLayerInfo = tileLayerModel.getObject();

        if (info instanceof LayerInfo) {
            createTileLayerLabelModel = new ResourceModel("createTileLayerForLayer");
            ResourceInfo resource = ((LayerInfo) info).getResource();
            // we need the _current_ name, regardless of it's name is being changed
            resource = ModificationProxy.unwrap(resource);
            originalLayerName = resource.getPrefixedName();
        } else if (info instanceof LayerGroupInfo) {
            createTileLayerLabelModel = new ResourceModel("createTileLayerForLayerGroup");
            // we need the _current_ name, regardless of if it's name is being changed
            LayerGroupInfo lgi = ModificationProxy.unwrap((LayerGroupInfo) info);
            originalLayerName = tileLayerName(lgi);
        } else {
            throw new IllegalArgumentException(
                    "Provided model does not target a LayerInfo nor a LayerGroupInfo: " + info);
        }

        TileLayer tileLayer = null;
        if (originalLayerName != null) {
            try {
                tileLayer = mediator.getTileLayerByName(originalLayerName);
            } catch (IllegalArgumentException notFound) {
                //
            }
        }
        cachedLayerExistedInitially = tileLayer != null;

        // UI construction phase
        add(confirmRemovalDialog = new GeoServerDialog("confirmRemovalDialog"));
        confirmRemovalDialog.setInitialWidth(360);
        confirmRemovalDialog.setInitialHeight(180);

        add(new Label("createTileLayerLabel", createTileLayerLabelModel));

        boolean doCreateTileLayer;
        if (tileLayerInfo.getId() != null) {
            doCreateTileLayer = true;
        } else if (isNew() && mediator.getConfig().isCacheLayersByDefault()) {
            doCreateTileLayer = true;
        } else {
            doCreateTileLayer = false;
        }
        add(createLayer = new CheckBox("createTileLayer", new Model<Boolean>(doCreateTileLayer)));
        createLayer.add(new AttributeModifier("title", true, new ResourceModel(
                "createTileLayer.title")));

        container = new WebMarkupContainer("container");
        container.setOutputMarkupId(true);
        add(container);

        configs = new WebMarkupContainer("configs");
        configs.setOutputMarkupId(true);
        container.add(configs);

        add(enabled = new CheckBox("enabled", new PropertyModel<Boolean>(getModel(), "enabled")));
        enabled.add(new AttributeModifier("title", true, new ResourceModel("enabled.title")));
        configs.add(enabled);

        List<Integer> metaTilingChoices = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
                14, 15, 16, 17, 18, 19, 20);
        IModel<Integer> metaTilingXModel = new PropertyModel<Integer>(getModel(), "metaTilingX");
        metaTilingX = new DropDownChoice<Integer>("metaTilingX", metaTilingXModel,
                metaTilingChoices);
        configs.add(metaTilingX);

        IModel<Integer> metaTilingYModel = new PropertyModel<Integer>(getModel(), "metaTilingY");
        metaTilingY = new DropDownChoice<Integer>("metaTilingY", metaTilingYModel,
                metaTilingChoices);
        configs.add(metaTilingY);

        IModel<Integer> gutterModel = new PropertyModel<Integer>(getModel(), "gutter");
        List<Integer> gutterChoices = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 50,
                100);
        gutter = new DropDownChoice<Integer>("gutter", gutterModel, gutterChoices);
        configs.add(gutter);

        IModel<Set<String>> mimeFormatsModel = new PropertyModel<Set<String>>(getModel(),
                "mimeFormats");

        cacheFormats = new CheckGroup<String>("cacheFormatsGroup", mimeFormatsModel);
        cacheFormats.setLabel(new ResourceModel("cacheFormats"));
        configs.add(cacheFormats);

        final List<String> formats = Arrays.asList("image/png", "image/png8", "image/jpeg",
                "image/gif");

        ListView<String> cacheFormatsList = new ListView<String>("cacheFormats", formats) {
            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(ListItem<String> item) {
                item.add(new Check<String>("cacheFormatsOption", item.getModel()));
                item.add(new Label("name", item.getModel()));
            }
        };
        cacheFormatsList.setReuseItems(true);// otherwise it looses state on invalid form state
                                             // submits
        cacheFormats.add(cacheFormatsList);

        IModel<Integer> expireCacheModel = new PropertyModel<Integer>(getModel(), "expireCache");
        expireCache = new TextField<Integer>("expireCache", expireCacheModel);
        configs.add(expireCache);
       
        IModel<Integer> expireClientsModel = new PropertyModel<Integer>(getModel(), "expireClients");
        expireClients = new TextField<Integer>("expireClients", expireClientsModel);
        configs.add(expireClients);
       
        IModel<Set<XMLGridSubset>> gridSubsetsModel;
        gridSubsetsModel = new PropertyModel<Set<XMLGridSubset>>(getModel(), "gridSubsets");
        gridSubsets = new GridSubsetsEditor("cachedGridsets", gridSubsetsModel);
        configs.add(gridSubsets);
       
        IModel<Set<ParameterFilter>> parameterFilterModel;
        parameterFilterModel = new PropertyModel<Set<ParameterFilter>>(getModel(), "parameterFilters");
        parameterFilters = new ParameterFilterEditor("parameterFilters", parameterFilterModel, layerModel);
        configs.add(parameterFilters);

        // behavior phase
        configs.setVisible(createLayer.getModelObject());
        setValidating(createLayer.getModelObject());

        createLayer.add(new OnChangeAjaxBehavior() {
            private static final long serialVersionUID = 1L;

            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                final boolean createTileLayer = createLayer.getModelObject().booleanValue();

                if (!createTileLayer && cachedLayerExistedInitially) {
                    confirmRemovalOfExistingTileLayer(target);
                } else {
                    updateConfigsVisibility(target);
                }

            }
        });
    }

    private boolean isNew() {
        GeoServerTileLayerInfoModel model = (GeoServerTileLayerInfoModel) super.getModel();
        return model.isNew();
    }

    public void save() {
        final GWC gwc = GWC.get();

        final CatalogInfo layer = layerModel.getObject();
        final GeoServerTileLayerInfo tileLayerInfo = getModelObject();
        final boolean tileLayerExists = gwc.hasTileLayer(layer);
        final boolean createLayer = this.createLayer.getModelObject().booleanValue();

        if (!createLayer) {
            if (tileLayerExists) {
                String tileLayerName = tileLayerInfo.getName();
                gwc.removeTileLayers(Arrays.asList(tileLayerName));
            }
            return;
        }

        // if we're creating a new layer, at this point the layer has already been created and hence
        // has an id
        Preconditions.checkState(layer.getId() != null);
        tileLayerInfo.setId(layer.getId());

        final String name;
        final GridSetBroker gridsets = gwc.getGridSetBroker();
        GeoServerTileLayer tileLayer;
        if (layer instanceof LayerGroupInfo) {
            LayerGroupInfo groupInfo = (LayerGroupInfo) layer;
            name = tileLayerName(groupInfo);
            tileLayer = new GeoServerTileLayer(groupInfo, gridsets, tileLayerInfo);
        } else {
            LayerInfo layerInfo = (LayerInfo) layer;
            name = tileLayerName(layerInfo);
            tileLayer = new GeoServerTileLayer(layerInfo, gridsets, tileLayerInfo);
        }

        tileLayerInfo.setName(name);

        if (tileLayerExists) {
            gwc.save(tileLayer);
        } else {
            gwc.add(tileLayer);
        }
    }



    private void updateConfigsVisibility(AjaxRequestTarget target) {
        final boolean createTileLayer = createLayer.getModelObject().booleanValue();
        setValidating(createTileLayer);
        configs.setVisible(createTileLayer);
        target.addComponent(container);
    }

    private void confirmRemovalOfExistingTileLayer(final AjaxRequestTarget origTarget) {
        // show confirm cache removal dialog for this layer
        confirmRemovalDialog.setTitle(new Model<String>("Confirm removal of cached contents?"));

        // if there is something to cancel, let's warn the user about what
        // could go wrong, and if the user accepts, let's delete what's needed
        confirmRemovalDialog.showOkCancel(origTarget, new GeoServerDialog.DialogDelegate() {
            private static final long serialVersionUID = 1L;

            @Override
            protected Component getContents(final String id) {
                // show a confirmation panel for all the objects we have to remove
                GWC gwc = GWC.get();
                Quota usedQuota = gwc.getUsedQuota(originalLayerName);
                if (usedQuota == null) {
                    usedQuota = new Quota();
                }
                String usedQuotaStr = usedQuota.toNiceString();
                return new Label(id, new ParamResourceModel("confirmTileLayerRemoval",
                        GeoServerTileLayerEditor.this, usedQuotaStr));
            }

            @Override
            protected boolean onSubmit(final AjaxRequestTarget target, final Component contents) {
                return true;
            }

            @Override
            public void onClose(final AjaxRequestTarget target) {
                target.addComponent(createLayer);
                updateConfigsVisibility(target);
            }

            @Override
            protected boolean onCancel(final AjaxRequestTarget target) {
                createLayer.setModelObject(Boolean.TRUE);
                final boolean closeWindow = true;
                return closeWindow;
            }
        });

    }

    private void setValidating(final boolean validate) {
        gridSubsets.setValidating(validate);
        cacheFormats.setRequired(validate);
    }

    /**
     * @see org.apache.wicket.markup.html.form.FormComponent#convertInput()
     */
    @Override
    protected void convertInput() {
        createLayer.processInput();
        final boolean createTileLayer = createLayer.getModelObject().booleanValue();

        GeoServerTileLayerInfo tileLayerInfo = getModelObject();

        if (createTileLayer) {
            enabled.processInput();
            expireCache.processInput();
            expireClients.processInput();
            metaTilingX.processInput();
            metaTilingY.processInput();
            gutter.processInput();
            cacheFormats.processInput();
            parameterFilters.processInput();
            gridSubsets.processInput();

            tileLayerInfo.setId(layerModel.getObject().getId());
            setConvertedInput(tileLayerInfo);
        } else {
            tileLayerInfo.setId(null);
            setConvertedInput(tileLayerInfo);
        }
        setModelObject(tileLayerInfo);
    }

    /**
     * @see org.apache.wicket.Component#onBeforeRender()
     */
    @Override
    protected void onBeforeRender() {
        super.onBeforeRender();
    }

}
TOP

Related Classes of org.geoserver.gwc.web.layer.GeoServerTileLayerEditor

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.