开源地图服务geoserver源代码分析&工作空间、数据存储

工作空间有点类似于一个目录,而geoserver的工作空间是数据目录下的特定文件夹。创建工作空间的代码位于如下图的位置。

对应的新建工作区页面则如下图所示。

我们来看一下,创建的该页面的代码。WorkspaceNewPage.java的构造函数利用wickte来创建填写提交表单。

public WorkspaceNewPage() {
        WorkspaceInfo ws = getCatalog().getFactory().createWorkspace();

        form =
                new Form<WorkspaceInfo>("form", new CompoundPropertyModel<WorkspaceInfo>(ws)) {
                    private static final long serialVersionUID = 6088042051374665053L;

                    @Override
                    protected void onSubmit() {
                        handleOnSubmit(form);
                    }
                };
        add(form);

        TextField<String> nameTextField = new TextField<String>("name");
        nameTextField.setRequired(true);
        nameTextField.add(new XMLNameValidator());
        nameTextField.add(
                new StringValidator() {

                    private static final long serialVersionUID = -5475431734680134780L;

                    @Override
                    public void validate(IValidatable<String> validatable) {
                        if (CatalogImpl.DEFAULT.equals(validatable.getValue())) {
                            validatable.error(
                                    new ValidationError("defaultWsError").addKey("defaultWsError"));
                        }
                    }
                });
        form.add(nameTextField.setRequired(true));

        nsUriTextField = new TextField<String>("uri", new Model<String>());
        // maybe a bit too restrictive, but better than not validation at all
        nsUriTextField.setRequired(true);
        nsUriTextField.add(new URIValidator());
        form.add(nsUriTextField);

        CheckBox defaultChk =
                new CheckBox("default", new PropertyModel<Boolean>(this, "defaultWs"));
        form.add(defaultChk);

        // add checkbox for isolated workspaces
        CheckBox isolatedChk = new CheckBox("isolated", new PropertyModel<>(ws, "isolated"));
        if (!getCatalog().getCatalogCapabilities().supportsIsolatedWorkspaces()) {
            // is isolated workspaces are not supported by the current catalog disable them
            isolatedChk.setEnabled(false);
        }
        form.add(isolatedChk);

        SubmitLink submitLink = new SubmitLink("submit", form);
        form.add(submitLink);
        form.setDefaultButton(submitLink);

        AjaxLink<Void> cancelLink =
                new AjaxLink<Void>("cancel") {
                    private static final long serialVersionUID = -1731475076965108576L;

                    @Override
                    public void onClick(AjaxRequestTarget target) {
                        doReturn(WorkspacePage.class);
                    }
                };
        form.add(cancelLink);
    }

注意里面的表单提交后的回调函数handleOnSubmit,

 private void handleOnSubmit(Form form) {
        Catalog catalog = getCatalog();
        // get the workspace information from the form
        WorkspaceInfo workspace = (WorkspaceInfo) form.getModelObject();
        NamespaceInfo namespace = catalog.getFactory().createNamespace();
        namespace.setPrefix(workspace.getName());
        namespace.setURI(nsUriTextField.getDefaultModelObjectAsString());
        namespace.setIsolated(workspace.isIsolated());
        // validate the workspace information adn associated namespace
        if (!validateAndReport(() -> catalog.validate(workspace, true), form)
                || !validateAndReport(() -> catalog.validate(namespace, true), form)) {
            // at least one validation fail
            return;
        }
        // store the workspace and associated namespace in the catalog
        try {
            catalog.add(workspace);
            catalog.add(namespace);
        } catch (Exception exception) {
            LOGGER.log(Level.INFO, "Error storing workspace related objects.", exception);
            cleanAndReport(exception, form);
        }
        // let's see if we need to tag this workspace as the default one
        if (defaultWs) {
            catalog.setDefaultWorkspace(workspace);
        }
        doReturn(WorkspacePage.class);
    }

catalog对工作空间进行了检校。然后再将工作空间和名字空间放到catalog中。检校函数主要做类似于是否名字重复等验证工作。函数如下所示。

 private boolean validateAndReport(Supplier<ValidationResult> validation, Form form) {
        // execute the validation
        ValidationResult validationResult;
        try {
            validationResult = validation.get();
        } catch (Exception exception) {
            // the validation it self may fail, for example if the workspace already exists
            LOGGER.log(Level.INFO, "Error validating workspace related objects.", exception);
            form.error(exception.getMessage());
            return false;
        }
        // if the validation was not successful report the found exceptions
        if (!validationResult.isValid()) {
            String message = validationResult.getErrosAsString(System.lineSeparator());
            LOGGER.log(Level.INFO, message);
            form.error(message);
            return false;
        }
        // validation was successful
        return true;
    }

如果说出现两次名字重复的工作空间,那么会抛出异常。在代码中则会抛出这样的异常。

而对应的桌面则显示如下的红色警告。

好了,看完工作空间后,下面来看数据存储。

我们这里选择【栅格数据源】,当然这个展示界面还为我们提供其他的数据源,具体的没有一一去研究,可以参考一下代码。

 public NewDataPage() {

        final boolean thereAreWorkspaces = !getCatalog().getWorkspaces().isEmpty();

        if (!thereAreWorkspaces) {
            super.error(
                    (String) new ResourceModel("NewDataPage.noWorkspacesErrorMessage").getObject());
        }

        final Form storeForm = new Form("storeForm");
        add(storeForm);

        final ArrayList<String> sortedDsNames =
                new ArrayList<String>(getAvailableDataStores().keySet());
        Collections.sort(sortedDsNames);

        final CatalogIconFactory icons = CatalogIconFactory.get();
        final ListView dataStoreLinks =
                new ListView("vectorResources", sortedDsNames) {
                    @Override
                    protected void populateItem(ListItem item) {
                        final String dataStoreFactoryName = item.getDefaultModelObjectAsString();
                        final DataAccessFactory factory =
                                getAvailableDataStores().get(dataStoreFactoryName);
                        final String description = factory.getDescription();
                        SubmitLink link;
                        link =
                                new SubmitLink("resourcelink") {
                                    @Override
                                    public void onSubmit() {
                                        setResponsePage(
                                                new DataAccessNewPage(dataStoreFactoryName));
                                    }
                                };
                        link.setEnabled(thereAreWorkspaces);
                        link.add(new Label("resourcelabel", dataStoreFactoryName));
                        item.add(link);
                        item.add(new Label("resourceDescription", description));
                        Image icon = new Image("storeIcon", icons.getStoreIcon(factory.getClass()));
                        // TODO: icons could provide a description too to be used in alt=...
                        icon.add(new AttributeModifier("alt", new Model("")));
                        item.add(icon);
                    }
                };

        final List<String> sortedCoverageNames = new ArrayList<String>();
        sortedCoverageNames.addAll(getAvailableCoverageStores().keySet());
        Collections.sort(sortedCoverageNames);

        final ListView coverageLinks =
                new ListView("rasterResources", sortedCoverageNames) {
                    @Override
                    protected void populateItem(ListItem item) {
                        final String coverageFactoryName = item.getDefaultModelObjectAsString();
                        final Map<String, Format> coverages = getAvailableCoverageStores();
                        Format format = coverages.get(coverageFactoryName);
                        final String description = format.getDescription();
                        SubmitLink link;
                        link =
                                new SubmitLink("resourcelink") {
                                    @Override
                                    public void onSubmit() {
                                        setResponsePage(
                                                new CoverageStoreNewPage(coverageFactoryName));
                                    }
                                };
                        link.setEnabled(thereAreWorkspaces);
                        link.add(new Label("resourcelabel", coverageFactoryName));
                        item.add(link);
                        item.add(new Label("resourceDescription", description));
                        Image icon = new Image("storeIcon", icons.getStoreIcon(format.getClass()));
                        // TODO: icons could provide a description too to be used in alt=...
                        icon.add(new AttributeModifier("alt", new Model("")));
                        item.add(icon);
                    }
                };

        final List<OtherStoreDescription> otherStores = getOtherStores();

        final ListView otherStoresLinks =
                new ListView("otherStores", otherStores) {
                    @Override
                    protected void populateItem(ListItem item) {
                        final OtherStoreDescription store =
                                (OtherStoreDescription) item.getModelObject();
                        SubmitLink link;
                        link =
                                new SubmitLink("resourcelink") {
                                    @Override
                                    public void onSubmit() {
                                        setResponsePage(store.configurationPage);
                                    }
                                };
                        link.setEnabled(thereAreWorkspaces);
                        link.add(
                                new Label(
                                        "resourcelabel",
                                        new ParamResourceModel(
                                                "other." + store.key, NewDataPage.this)));
                        item.add(link);
                        item.add(
                                new Label(
                                        "resourceDescription",
                                        new ParamResourceModel(
                                                "other." + store.key + ".description",
                                                NewDataPage.this)));
                        Image icon = new Image("storeIcon", store.icon);
                        // TODO: icons could provide a description too to be used in alt=...
                        icon.add(new AttributeModifier("alt", new Model("")));
                        item.add(icon);
                    }
                };

        storeForm.add(dataStoreLinks);
        storeForm.add(coverageLinks);
        storeForm.add(otherStoresLinks);
    }

栅格数据源则使用下面的函数展示出来。

 /** @return the name/description set of available raster formats */
    private Map<String, Format> getAvailableCoverageStores() {
        if (coverages == null) {
            Format[] availableFormats = GridFormatFinder.getFormatArray();
            Map<String, Format> formatNames = new HashMap<String, Format>();
            for (Format format : availableFormats) {
                formatNames.put(format.getName(), format);
            }
            coverages = formatNames;
        }
        return coverages;
    }

当点击数据源后,进入到如下的界面。

显然进入到一个page页面,而这里是对应CoverageStoreNewPage类。到选择好数据,并点击【保存】后,如下图进入到如的代码。

protected void onSave(final CoverageStoreInfo info, AjaxRequestTarget target)
            throws IllegalArgumentException {
        final Catalog catalog = getCatalog();

        /*
         * Try saving a copy of it so if the process fails somehow the original "info" does not end
         * up with an id set
         */
        CoverageStoreInfo expandedStore = getCatalog().getResourcePool().clone(info, true);
        CoverageStoreInfo savedStore = catalog.getFactory().createCoverageStore();

        // GR: this shouldn't fail, the Catalog.save(StoreInfo) API does not declare any action in
        // case
        // of a failure!... strange, why a save can't fail?
        // Still, be cautious and wrap it in a try/catch block so the page does not blow up
        try {
            // GeoServer Env substitution; validate first
            catalog.validate(expandedStore, false).throwIfInvalid();

            // GeoServer Env substitution; force to *AVOID* resolving env placeholders...
            savedStore = catalog.getResourcePool().clone(info, false);
            // ... and save
            catalog.save(savedStore);
        } catch (RuntimeException e) {
            LOGGER.log(Level.INFO, "Adding the store for " + info.getURL(), e);
            throw new IllegalArgumentException(
                    "The coverage store could not be saved. Failure message: " + e.getMessage());
        }

        onSuccessfulSave(info, catalog, savedStore);
    }

    protected void onSuccessfulSave(
            final CoverageStoreInfo info, final Catalog catalog, CoverageStoreInfo savedStore) {
        // the StoreInfo save succeeded... try to present the list of coverages (well, _the_
        // coverage while the getotools coverage api does not allow for more than one
        NewLayerPage layerChooserPage;
        CoverageStoreInfo expandedStore;
        try {
            expandedStore = catalog.getResourcePool().clone(savedStore, true);
            // The ID is assigned by the catalog and therefore cannot be cloned
            layerChooserPage = new NewLayerPage(savedStore.getId());
        } catch (RuntimeException e) {
            LOGGER.log(Level.INFO, "Getting list of coverages for saved store " + info.getURL(), e);
            // doh, can't present the list of coverages, means saving the StoreInfo is meaningless.
            try { // be extra cautious
                catalog.remove(savedStore);
            } catch (RuntimeErrorException shouldNotHappen) {
                LOGGER.log(Level.WARNING, "Can't remove CoverageStoreInfo after adding it!", e);
            }
            // tell the caller why we failed...
            throw new IllegalArgumentException(e.getMessage(), e);
        }

        setResponsePage(layerChooserPage);
    }

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yGIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值