Package org.geoserver.wms.eo.web

Source Code of org.geoserver.wms.eo.web.EoLayerGroupAbstractPage$GroupNameValidator

/* (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.wms.eo.web;

import java.util.Collections;
import java.util.List;
import java.util.logging.Level;

import org.apache.wicket.Component;
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.html.form.TextArea;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.convert.IConverter;
import org.apache.wicket.validation.IValidatable;
import org.apache.wicket.validation.validator.AbstractValidator;
import org.geoserver.catalog.CatalogBuilder;
import org.geoserver.catalog.CoverageInfo;
import org.geoserver.catalog.CoverageStoreInfo;
import org.geoserver.catalog.DimensionInfo;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerGroupInfo.Mode;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.MetadataMap;
import org.geoserver.catalog.PublishedInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.web.ComponentAuthorizer;
import org.geoserver.web.GeoServerSecuredPage;
import org.geoserver.web.data.layergroup.LayerGroupDetachableModel;
import org.geoserver.web.data.layergroup.LayerInfoConverter;
import org.geoserver.web.data.layergroup.RootLayerEntryPanel;
import org.geoserver.web.data.layergroup.StyleInfoConverter;
import org.geoserver.web.data.store.CoverageStoreNewPage;
import org.geoserver.web.data.workspace.WorkspaceChoiceRenderer;
import org.geoserver.web.data.workspace.WorkspacesModel;
import org.geoserver.web.wicket.EnvelopePanel;
import org.geoserver.web.wicket.GeoServerAjaxFormLink;
import org.geoserver.web.wicket.GeoServerDialog;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geoserver.wms.eo.EoCatalogBuilder;
import org.geoserver.wms.eo.EoLayerType;
import org.geotools.coverage.grid.io.StructuredGridCoverage2DReader;
import org.geotools.gce.imagemosaic.ImageMosaicFormat;
import org.opengis.referencing.crs.CoordinateReferenceSystem;


/**
* Handles layer group
*/
@SuppressWarnings({ "rawtypes", "unchecked", "serial" })
public abstract class EoLayerGroupAbstractPage extends GeoServerSecuredPage {

    public static final String GROUP = "group";
    IModel<LayerGroupInfo> lgModel;
    EnvelopePanel envelopePanel;
    EoLayerGroupEntryPanel lgEntryPanel;
    String layerGroupId;
    protected RootLayerEntryPanel rootLayerPanel;   
    TextField<String> name;
    ModalWindow popupWindow;
    String groupName;
    private GeoServerDialog dialog;
   
    /**
     * Subclasses must call this method to initialize the UI for this page
     * @param layerGroup
     */
    protected void initUI(LayerGroupInfo layerGroup) {
        this.returnPageClass = EoLayerGroupPage.class;
        lgModel = new LayerGroupDetachableModel( layerGroup );
        layerGroupId = layerGroup.getId();
       
        add(popupWindow = new ModalWindow("popup"));
        add(dialog = new GeoServerDialog("dialog"));

        Form form = new Form( "form", new CompoundPropertyModel( lgModel ) ) {
            @Override
            public IConverter getConverter(Class<?> type) {
                if (LayerInfo.class.isAssignableFrom(type)) {
                    return new LayerInfoConverter();
                } else if (StyleInfo.class.isAssignableFrom(type)) {
                    return new StyleInfoConverter();
                } else {
                    return super.getConverter(type);
                }
            }
        };
       
        add(form);

        name = new TextField<String>("name");
        name.setRequired(true);
        groupName = layerGroup.getName();
        form.add(name);

        form.add(new TextField("title"));
        form.add(new TextArea("abstract"));
       
        final DropDownChoice<WorkspaceInfo> wsChoice =
                new DropDownChoice("workspace", new WorkspacesModel(), new WorkspaceChoiceRenderer());
        wsChoice.setNullValid(true);
        if (!isAuthenticatedAsAdmin()) {
            wsChoice.setNullValid(false);
            wsChoice.setRequired(true);
        }

        form.add(wsChoice);

        //bounding box
        form.add(envelopePanel = new EnvelopePanel( "bounds" )/*.setReadOnly(true)*/);
        envelopePanel.setRequired(true);
        envelopePanel.setCRSFieldVisible(true);
        envelopePanel.setCrsRequired(true);
        envelopePanel.setOutputMarkupId( true );
       
        form.add(new GeoServerAjaxFormLink( "generateBounds") {
            @Override
            public void onClick(AjaxRequestTarget target, Form form) {
                // build a layer group with the current contents of the group
                LayerGroupInfo lg = getCatalog().getFactory().createLayerGroup();
                for ( EoLayerGroupEntry entry : lgEntryPanel.getEntries() ) {
                    lg.getLayers().add(entry.getLayer());
                    lg.getStyles().add(entry.getStyle());
                }
               
                try {
                    // grab the eventually manually inserted
                    CoordinateReferenceSystem crs = envelopePanel.getCoordinateReferenceSystem();
                    
                    if ( crs != null ) {
                        //ensure the bounds calculated in terms of the user specified crs
                        new CatalogBuilder( getCatalog() ).calculateLayerGroupBounds( lg, crs );
                    }
                    else {
                        //calculate from scratch
                        new CatalogBuilder( getCatalog() ).calculateLayerGroupBounds( lg );
                    }
                   
                    envelopePanel.setModelObject( lg.getBounds() );
                    target.addComponent( envelopePanel );
                   
                }
                catch (Exception e) {
                    throw new WicketRuntimeException( e );
                }
            }
        });
       
        form.add(lgEntryPanel = new EoLayerGroupEntryPanel( "layers", layerGroup, popupWindow ));
        lgEntryPanel.setOutputMarkupId(true);
       
        EoLayerTypeRenderer eoLayerTypeRenderer = new EoLayerTypeRenderer();
        final DropDownChoice<EoLayerType> layerTypes = new DropDownChoice<EoLayerType>("layerType", EoLayerType.getRegularTypes(), eoLayerTypeRenderer);
        layerTypes.setModel(new Model<EoLayerType>(null));
        layerTypes.setOutputMarkupId(true);
        form.add(layerTypes);
       
        final GeoServerAjaxFormLink createStoreLink = new GeoServerAjaxFormLink( "createStore" ) {
            @Override
            public void onClick(AjaxRequestTarget target, Form form) {
                final String layerGroupName = getNonNullGroupName(target);
                if(layerGroupName != null) {
                    CoverageStoreNewPage coverageStoreCreator = new CoverageStoreNewPage(new ImageMosaicFormat().getName()) {
                        protected void onSuccessfulSave(org.geoserver.catalog.CoverageStoreInfo info, org.geoserver.catalog.Catalog catalog, org.geoserver.catalog.CoverageStoreInfo savedStore) {
                            EoCoverageSelectorPage page = new EoCoverageSelectorPage(EoLayerGroupAbstractPage.this, layerGroupName, savedStore.getId());
                            setResponsePage(page);
                        };
                    };
                    setResponsePage(coverageStoreCreator);
                } else {
                    dialog.showInfo(target, null, new ParamResourceModel("layerInfoTitle", EoLayerGroupAbstractPage.this), new ParamResourceModel("provideGroupName", EoLayerGroupAbstractPage.this));
                }
            }
        };
        createStoreLink.setOutputMarkupId(true);
        form.add( createStoreLink);
       
        final GeoServerAjaxFormLink addFromStoreLink = new GeoServerAjaxFormLink( "addFromStore" ) {
            @Override
            public void onClick(AjaxRequestTarget target, Form form) {
                final String layerGroupName = getNonNullGroupName(target);
                if(layerGroupName != null) {
                    EoCoverageSelectorPage page = new EoCoverageSelectorPage(EoLayerGroupAbstractPage.this, layerGroupName);
                    setResponsePage(page);
                } else {
                    dialog.showInfo(target, null, new ParamResourceModel("layerInfoTitle", EoLayerGroupAbstractPage.this), new ParamResourceModel("provideGroupName", EoLayerGroupAbstractPage.this));
                }
            }
               
        };
        addFromStoreLink.setOutputMarkupId(true);
        form.add( addFromStoreLink);
       
        final GeoServerAjaxFormLink addLayerLink = new GeoServerAjaxFormLink( "addLayer" ) {
            @Override
            public void onClick(AjaxRequestTarget target, Form form) {
                popupWindow.setInitialHeight( 375 );
                popupWindow.setInitialWidth( 525 );
                popupWindow.setTitle(new ParamResourceModel("chooseLayer", this));
                layerTypes.processInput();
                final EoLayerType layerType = layerTypes.getModelObject();
                popupWindow.setContent( new EoLayerListPanel(popupWindow.getContentId(), layerType,  lgEntryPanel.entryProvider) {
                    @Override
                    protected void handleLayer(LayerInfo layer, AjaxRequestTarget target) {
                        popupWindow.close( target );
                       
                        layer.getMetadata().put(EoLayerType.KEY, layerType);
                        lgEntryPanel.entryProvider.getItems().add(
                            new EoLayerGroupEntry( layer, layer.getDefaultStyle(), groupName));
                       
                        target.addComponent(lgEntryPanel);
                        layerTypes.setDefaultModelObject(layerTypes.getDefaultModelObject());
                        target.addComponent(layerTypes);
                    }
                });
               
                popupWindow.show(target);
            }
        };
        addLayerLink.setEnabled(false);
        form.add( addLayerLink);
       
        final DropDownChoice<EoLayerGroupEntry> outlinesEntryChooser = new DropDownChoice<EoLayerGroupEntry>("sourceLayer", new OutlineSourceModel(lgEntryPanel.items), new LayerGroupEntryRenderer());
        outlinesEntryChooser.setModel(new Model<EoLayerGroupEntry>(null));
        outlinesEntryChooser.setOutputMarkupId(true);
        outlinesEntryChooser.setEnabled(!outlinesPresent(lgEntryPanel.items));
        form.add(outlinesEntryChooser);
       
        outlinesEntryChooser.add(new AjaxFormComponentUpdatingBehavior("onchange") {

            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                wsChoice.processInput();
                WorkspaceInfo ws = (WorkspaceInfo) wsChoice.getDefaultModelObject();
                outlinesEntryChooser.processInput();
                EoLayerGroupEntry entry = outlinesEntryChooser.getModelObject();
                try {
                    EoCatalogBuilder builder = new EoCatalogBuilder(getCatalog());
                    CoverageInfo coverage = (CoverageInfo) ((LayerInfo) entry.getLayer()).getResource();
                    CoverageStoreInfo store = coverage.getStore();
                    String url = store.getURL();
                    StructuredGridCoverage2DReader reader = (StructuredGridCoverage2DReader) coverage.getGridCoverageReader(null, null);
                    LayerInfo layer = builder.createEoOutlineLayer(url, ws, groupName, coverage.getNativeCoverageName(), reader);
                    lgEntryPanel.items.add(new EoLayerGroupEntry(layer, layer.getDefaultStyle(), groupName));
                } catch(Exception e) {
                    LOGGER.log(Level.SEVERE, "Failed to create outlines layer", e);
                    String layerName = entry.getLayer().prefixedName();
                    error(new ParamResourceModel("outlinesCreationError", EoLayerGroupAbstractPage.this, layerName, e.getMessage()).getString());
                } finally {
                    outlinesEntryChooser.setDefaultModelObject(null);
                }
                target.addComponent(lgEntryPanel);
                target.addComponent(getFeedbackPanel());
                target.addComponent(outlinesEntryChooser);
            }
           
        });
       
        layerTypes.add(new AjaxFormComponentUpdatingBehavior("onchange") {

            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                layerTypes.processInput();
                boolean input = layerTypes.getModelObject() != null;
                addLayerLink.setEnabled(input);
                target.addComponent(addLayerLink);
            }
           
        });
       
        name.add(new AjaxFormComponentUpdatingBehavior("onblur") {

            @Override
            protected void onUpdate(AjaxRequestTarget target) {
                groupName = name.getInput();
                boolean nameAvailable = groupName != null && !"".equals(groupName.trim());
                if(!nameAvailable) {
                    info(new ParamResourceModel("provideGroupName", EoLayerGroupAbstractPage.this).getString());
                } else {
                    // inform the user about possible layer renames
                    if(isLayerRenameRequired(groupName)) {
                        info (new ParamResourceModel("layerRenameWarning", EoLayerGroupAbstractPage.this, groupName).getString());
                    }
                }
                target.addComponent(createStoreLink);
                target.addComponent(addFromStoreLink);
                target.addComponent(getFeedbackPanel());
            }
           
        });
        if(name.getDefaultModelObject() == null || "".equals(name.getDefaultModelObject())) {
            info(new ParamResourceModel("provideGroupName", this).getString());
        }
       
        form.add(saveLink());
        form.add(cancelLink());
    }
   
    /**
     * True if we already have an outline layer, false otherwise
     * @param items
     * @return
     */
    private boolean outlinesPresent(List<EoLayerGroupEntry> items) {
        for (EoLayerGroupEntry entry : items) {
            if(entry.getLayerType() == EoLayerType.COVERAGE_OUTLINE) {
                return true;
            }
        }
       
        return false;
    }

    private boolean isLayerRenameRequired(String layerGroupName) {
        String prefix = layerGroupName + "_";
        for(EoLayerGroupEntry entry : lgEntryPanel.entryProvider.getItems()) {
            String expectedName = prefix + entry.getLayerSubName();
            if(!expectedName.equals(entry.getLayer().getName())) {
                return true;
            }
        }
       
        return false;
    }

   
    protected String getNonNullGroupName(AjaxRequestTarget target) {
        if(groupName == null || "".equals(groupName.trim())) {
            error("Please given a name to the layer grup before adding layers into it");
            return null;
        }
       
        return groupName;
    }


    private Component cancelLink() {
        return new AjaxLink<String>("cancel") {
            @Override
            public void onClick(AjaxRequestTarget target) {
                doReturn();
            }
        };
    }

    private SubmitLink saveLink() {
        return new SubmitLink("save"){
            @Override
            public void onSubmit() {
                // validation
                if(lgEntryPanel.getEntries().size() == 0) {
                    error((String) new ParamResourceModel("oneLayerMinimum", getPage()).getObject());
                    return;
                }

                LayerGroupInfo lg = (LayerGroupInfo) lgModel.getObject();

                // update the layer group entries
                lg.getLayers().clear();
                lg.getStyles().clear();
                for ( EoLayerGroupEntry entry : lgEntryPanel.getEntries() ) {
                    PublishedInfo pi = entry.getLayer();
                    if(pi instanceof LayerInfo) {
                        LayerInfo li = getCatalog().getLayer(pi.getId());
                        String expectedName = lg.getName() + "_" + entry.getLayerSubName();
                        String actualName = li.getName();
                        if(!expectedName.equals(actualName)) {
                            ResourceInfo resource = li.getResource();
                            li.setName(expectedName);
                            resource.setName(expectedName);
                            getCatalog().save(resource);
                            getCatalog().save(li);
                        }
                        lg.getLayers().add(li);
                        lg.getStyles().add(entry.getStyle());
                    }
                }

                try {
                    EoLayerGroupAbstractPage.this.save();
                } catch(Exception e) {
                    error(e);
                    LOGGER.log(Level.WARNING, "Error adding/modifying layer group.", e);   
                }
               
            }
        };
    }
   
    private final void save() {
        LayerGroupInfo lg = (LayerGroupInfo) lgModel.getObject();
        if(validateLayerGroupContents(lg)) {
            onSubmit(lg);
        }
    }
   
    private boolean validateLayerGroupContents(LayerGroupInfo lg) {
        boolean valid = true;
        List<EoLayerGroupEntry> items = lgEntryPanel.items;
        int browseCount = 0;
        LayerInfo browseLayer = null;
        StyleInfo browseLayerStyle = null;
        int bandsCount = 0;
        for (EoLayerGroupEntry entry : items) {
           
            if(!(entry.getLayer() instanceof LayerInfo)) {
                error(new ParamResourceModel("nestedLayerGroupInvalid", this));
            } else {
                EoLayerType type = entry.getLayerType();
               
                // count band and browse layers
                switch(type) {
                case BAND_COVERAGE:
                    bandsCount++;
                    break;
                case BROWSE_IMAGE:
                    browseCount++;
                    browseLayer = (LayerInfo) entry.getLayer();
                    browseLayerStyle = entry.getStyle();
                    break;
                default:
                    break;
                }
               
                if(!checkDimensions(entry)) {
                    valid = false;
                }
            }
        }
       
        if(browseCount != 1) {
            error(new ParamResourceModel("invalidBrowseCount", this, browseCount).getString());
            valid = false;
        }
       
        if(bandsCount > 1) {
            error(new ParamResourceModel("invalidBandsCount", this, bandsCount).getString());
            valid = false;
        }
       
        if(valid) {
            // set the layer root
            lg.setRootLayer(browseLayer);
            lg.setRootLayerStyle(browseLayerStyle);
            lg.setMode(Mode.EO);
        }

        return valid;
    }
   
    private boolean checkDimensions(EoLayerGroupEntry entry) {
        LayerInfo layer = (LayerInfo) entry.getLayer();
        MetadataMap metadata = layer.getResource().getMetadata();
        DimensionInfo timeDimension = metadata.get(ResourceInfo.TIME, DimensionInfo.class);
        boolean timeAvaiable = timeDimension != null && timeDimension.isEnabled();
        if(!timeAvaiable) {
            error(new ParamResourceModel("EoLayerGroupError.invalidLayer", null, layer.getName()).getString());
            return false;
        } else if(entry.getLayerType() != EoLayerType.BAND_COVERAGE) {
            return true;
        }
       
        // ok, has time, and it's a band layer. Does it have any extra dimension that can be
        // imagined to be used as a band selector?
        DimensionInfo elevationDimension = metadata.get(ResourceInfo.ELEVATION, DimensionInfo.class);
        if(elevationDimension != null && elevationDimension.isEnabled()) {
            return true;
        }
       
        // look for custom dimensions
        for (String key : metadata.keySet()) {
            if(key != null && key.startsWith(ResourceInfo.CUSTOM_DIMENSION_PREFIX)) {
                DimensionInfo di = metadata.get(key, DimensionInfo.class);
                if(di != null && di.isEnabled()) {
                    return true;
                }
            }
        }
       
        // found nothing, the layer is not valid
        error(new ParamResourceModel("EoLayerGroupError.invalidBandCoverage", null, layer.getName()).getString());
        return false;
    }

    /**
     * Subclasses
     */
    protected abstract void onSubmit(LayerGroupInfo lg);
   
    class GroupNameValidator extends AbstractValidator {

        @Override
        protected void onValidate(IValidatable validatable) {
            String name = (String) validatable.getValue();
            LayerGroupInfo other = getCatalog().getLayerGroupByName(name);
            if(other != null && (layerGroupId == null || !other.getId().equals(layerGroupId))) {
                error(validatable, "duplicateGroupNameError", Collections.singletonMap("name", name));
            }
        }
       
    }
   
    @Override
    protected ComponentAuthorizer getPageAuthorizer() {
        return ComponentAuthorizer.WORKSPACE_ADMIN;
    }
}
TOP

Related Classes of org.geoserver.wms.eo.web.EoLayerGroupAbstractPage$GroupNameValidator

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.