@Override public void validate(IValidatable<String> validatable) { String vcName = validatable.getValue(); final CoverageStoreInfo store = getCatalog().getStore(storeId, CoverageStoreInfo.class); List<CoverageInfo> coverages = getCatalog().getCoveragesByCoverageStore(store); for (CoverageInfo curr : coverages) { CoverageView currvc = curr.getMetadata().get(CoverageView.COVERAGE_VIEW, CoverageView.class); if (currvc != null) { if (coverageInfoId == null || !coverageInfoId.equals(curr.getId())) { if (currvc.getName().equals(vcName) && newCoverage) { Map<String, Object> map = new HashMap<>(); map.put("name", vcName); map.put("coverageName", curr.getName()); IValidationError err = new ValidationError("duplicateCoverageViewName") .addKey("duplicateCoverageViewName") .setVariables(map); validatable.error(err); return; } } } } }
/** @param cv */ private void handleCoverageOfferingBrief(CoverageInfo cv) { if (cv.isEnabled()) { start("wcs:CoverageOfferingBrief"); String tmp; for (MetadataLinkInfo mdl : cv.getMetadataLinks()) handleMetadataLink(mdl); tmp = cv.getDescription(); if ((tmp != null) && (tmp != "")) { element("wcs:description", tmp); } tmp = cv.getPrefixedName(); if ((tmp != null) && (tmp != "")) { element("wcs:name", tmp); } tmp = cv.getTitle(); if ((tmp != null) && (tmp != "")) { element("wcs:label", tmp); } CoverageStoreInfo csinfo = cv.getStore(); if (csinfo == null) { throw new WcsException( "Unable to acquire coverage store resource for coverage: " + cv.getName()); } AbstractGridCoverage2DReader reader = null; try { reader = (AbstractGridCoverage2DReader) catalog .getResourcePool() .getGridCoverageReader(csinfo, GeoTools.getDefaultHints()); } catch (IOException e) { LOGGER.severe( "Unable to acquire a reader for this coverage with format: " + csinfo.getFormat().getName()); } if (reader == null) throw new WcsException( "Unable to acquire a reader for this coverage with format: " + csinfo.getFormat().getName()); DimensionInfo timeInfo = cv.getMetadata().get(ResourceInfo.TIME, DimensionInfo.class); ReaderDimensionsAccessor dimensions = new ReaderDimensionsAccessor(reader); handleEnvelope(cv.getLatLonBoundingBox(), timeInfo, dimensions); handleKeywords(cv.getKeywords()); end("wcs:CoverageOfferingBrief"); } }
/** * Test that changing a datastore's workspace updates the datastore's "namespace" parameter as * well as the namespace of its previously configured resources */ public void testWorkspaceSyncsUpWithNamespace() { final Catalog catalog = getCatalog(); final FormTester formTester = tester.newFormTester("rasterStoreForm"); final String wsDropdownPath = "rasterStoreForm:workspacePanel:border:paramValue"; tester.assertModelValue(wsDropdownPath, catalog.getWorkspaceByName(MockData.WCS_PREFIX)); // select the fifth item in the drop down, which is the cdf workspace formTester.select("workspacePanel:border:paramValue", 2); // weird on this test I need to both call form.submit() and also simulate clicking on the // ajax "save" link for the model to be updated. On a running geoserver instance it works ok // though formTester.submit(); final boolean isAjax = true; tester.clickLink("rasterStoreForm:save", isAjax); // did the save finish normally? tester.assertRenderedPage(StorePage.class); CoverageStoreInfo store = catalog.getCoverageStore(coverageStore.getId()); WorkspaceInfo workspace = store.getWorkspace(); assertFalse(MockData.WCS_PREFIX.equals(workspace.getName())); // was the namespace for the datastore resources updated? List<CoverageInfo> resourcesByStore; resourcesByStore = catalog.getResourcesByStore(store, CoverageInfo.class); assertTrue(resourcesByStore.size() > 0); for (CoverageInfo cv : resourcesByStore) { assertEquals( "Namespace for " + cv.getName() + " was not updated", workspace.getName(), cv.getNamespace().getPrefix()); } }
/** Reads the catalog from disk. */ Catalog readCatalog(XStreamPersister xp) throws Exception { CatalogImpl catalog = new CatalogImpl(); catalog.setResourceLoader(resourceLoader); xp.setCatalog(catalog); xp.setUnwrapNulls(false); CatalogFactory factory = catalog.getFactory(); // global styles loadStyles(resourceLoader.find("styles"), catalog, xp); // workspaces, stores, and resources File workspaces = resourceLoader.find("workspaces"); if (workspaces != null) { // do a first quick scan over all workspaces, setting the default File dws = new File(workspaces, "default.xml"); WorkspaceInfo defaultWorkspace = null; if (dws.exists()) { try { defaultWorkspace = depersist(xp, dws, WorkspaceInfo.class); LOGGER.info("Loaded default workspace " + defaultWorkspace.getName()); } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to load default workspace", e); } } else { LOGGER.warning("No default workspace was found."); } for (File wsd : list(workspaces, DirectoryFileFilter.INSTANCE)) { File f = new File(wsd, "workspace.xml"); if (!f.exists()) { continue; } WorkspaceInfo ws = null; try { ws = depersist(xp, f, WorkspaceInfo.class); catalog.add(ws); } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to load workspace '" + wsd.getName() + "'", e); continue; } LOGGER.info("Loaded workspace '" + ws.getName() + "'"); // load the namespace File nsf = new File(wsd, "namespace.xml"); NamespaceInfo ns = null; if (nsf.exists()) { try { ns = depersist(xp, nsf, NamespaceInfo.class); catalog.add(ns); } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to load namespace for '" + wsd.getName() + "'", e); } } // set the default workspace, this value might be null in the case of coming from a // 2.0.0 data directory. See http://jira.codehaus.org/browse/GEOS-3440 if (defaultWorkspace != null) { if (ws.getName().equals(defaultWorkspace.getName())) { catalog.setDefaultWorkspace(ws); if (ns != null) { catalog.setDefaultNamespace(ns); } } } else { // create the default.xml file defaultWorkspace = catalog.getDefaultWorkspace(); if (defaultWorkspace != null) { try { persist(xp, defaultWorkspace, dws); } catch (Exception e) { LOGGER.log( Level.WARNING, "Failed to persist default workspace '" + wsd.getName() + "'", e); } } } // load the styles for the workspace File styles = resourceLoader.find(wsd, "styles"); if (styles != null) { loadStyles(styles, catalog, xp); } } for (File wsd : list(workspaces, DirectoryFileFilter.INSTANCE)) { // load the stores for this workspace for (File sd : list(wsd, DirectoryFileFilter.INSTANCE)) { File f = new File(sd, "datastore.xml"); if (f.exists()) { // load as a datastore DataStoreInfo ds = null; try { ds = depersist(xp, f, DataStoreInfo.class); catalog.add(ds); LOGGER.info("Loaded data store '" + ds.getName() + "'"); if (ds.isEnabled()) { // connect to the datastore to determine if we should disable it try { ds.getDataStore(null); } catch (Throwable t) { LOGGER.warning("Error connecting to '" + ds.getName() + "'. Disabling."); LOGGER.log(Level.INFO, "", t); ds.setError(t); ds.setEnabled(false); } } } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to load data store '" + sd.getName() + "'", e); continue; } // load feature types for (File ftd : list(sd, DirectoryFileFilter.INSTANCE)) { f = new File(ftd, "featuretype.xml"); if (f.exists()) { FeatureTypeInfo ft = null; try { ft = depersist(xp, f, FeatureTypeInfo.class); } catch (Exception e) { LOGGER.log( Level.WARNING, "Failed to load feature type '" + ftd.getName() + "'", e); continue; } catalog.add(ft); LOGGER.info("Loaded feature type '" + ds.getName() + "'"); f = new File(ftd, "layer.xml"); if (f.exists()) { try { LayerInfo l = depersist(xp, f, LayerInfo.class); catalog.add(l); LOGGER.info("Loaded layer '" + l.getName() + "'"); } catch (Exception e) { LOGGER.log( Level.WARNING, "Failed to load layer for feature type '" + ft.getName() + "'", e); } } } else { LOGGER.warning("Ignoring feature type directory " + ftd.getAbsolutePath()); } } } else { // look for a coverage store f = new File(sd, "coveragestore.xml"); if (f.exists()) { CoverageStoreInfo cs = null; try { cs = depersist(xp, f, CoverageStoreInfo.class); catalog.add(cs); LOGGER.info("Loaded coverage store '" + cs.getName() + "'"); } catch (Exception e) { LOGGER.log( Level.WARNING, "Failed to load coverage store '" + sd.getName() + "'", e); continue; } // load coverages for (File cd : list(sd, DirectoryFileFilter.INSTANCE)) { f = new File(cd, "coverage.xml"); if (f.exists()) { CoverageInfo c = null; try { c = depersist(xp, f, CoverageInfo.class); catalog.add(c); LOGGER.info("Loaded coverage '" + cs.getName() + "'"); } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to load coverage '" + cd.getName() + "'", e); continue; } f = new File(cd, "layer.xml"); if (f.exists()) { try { LayerInfo l = depersist(xp, f, LayerInfo.class); catalog.add(l); LOGGER.info("Loaded layer '" + l.getName() + "'"); } catch (Exception e) { LOGGER.log( Level.WARNING, "Failed to load layer coverage '" + c.getName() + "'", e); } } } else { LOGGER.warning("Ignoring coverage directory " + cd.getAbsolutePath()); } } } else { f = new File(sd, "wmsstore.xml"); if (f.exists()) { WMSStoreInfo wms = null; try { wms = depersist(xp, f, WMSStoreInfo.class); catalog.add(wms); LOGGER.info("Loaded wmsstore '" + wms.getName() + "'"); } catch (Exception e) { LOGGER.log(Level.WARNING, "Failed to load wms store '" + sd.getName() + "'", e); continue; } // load wms layers for (File cd : list(sd, DirectoryFileFilter.INSTANCE)) { f = new File(cd, "wmslayer.xml"); if (f.exists()) { WMSLayerInfo wl = null; try { wl = depersist(xp, f, WMSLayerInfo.class); catalog.add(wl); LOGGER.info("Loaded wms layer'" + wl.getName() + "'"); } catch (Exception e) { LOGGER.log( Level.WARNING, "Failed to load wms layer '" + cd.getName() + "'", e); continue; } f = new File(cd, "layer.xml"); if (f.exists()) { try { LayerInfo l = depersist(xp, f, LayerInfo.class); catalog.add(l); LOGGER.info("Loaded layer '" + l.getName() + "'"); } catch (Exception e) { LOGGER.log( Level.WARNING, "Failed to load cascaded wms layer '" + wl.getName() + "'", e); } } } else { LOGGER.warning("Ignoring coverage directory " + cd.getAbsolutePath()); } } } else if (!isConfigDirectory(sd)) { LOGGER.warning("Ignoring store directory '" + sd.getName() + "'"); continue; } } } } // load hte layer groups for this workspace File layergroups = resourceLoader.find(wsd, "layergroups"); if (layergroups != null) { loadLayerGroups(layergroups, catalog, xp); } } } else { LOGGER.warning("No 'workspaces' directory found, unable to load any stores."); } // namespaces // layergroups File layergroups = resourceLoader.find("layergroups"); if (layergroups != null) { loadLayerGroups(layergroups, catalog, xp); } xp.setUnwrapNulls(true); catalog.resolve(); return catalog; }
@DescribeResult(name = "layerName", description = "Name of the new featuretype, with workspace") public String execute( @DescribeParameter(name = "features", min = 0, description = "Input feature collection") SimpleFeatureCollection features, @DescribeParameter(name = "coverage", min = 0, description = "Input raster") GridCoverage2D coverage, @DescribeParameter( name = "workspace", min = 0, description = "Target workspace (default is the system default)") String workspace, @DescribeParameter( name = "store", min = 0, description = "Target store (default is the workspace default)") String store, @DescribeParameter( name = "name", min = 0, description = "Name of the new featuretype/coverage (default is the name of the features in the collection)") String name, @DescribeParameter( name = "srs", min = 0, description = "Target coordinate reference system (default is based on source when possible)") CoordinateReferenceSystem srs, @DescribeParameter( name = "srsHandling", min = 0, description = "Desired SRS handling (default is FORCE_DECLARED, others are REPROJECT_TO_DECLARED or NONE)") ProjectionPolicy srsHandling, @DescribeParameter( name = "styleName", min = 0, description = "Name of the style to be associated with the layer (default is a standard geometry-specific style)") String styleName) throws ProcessException { // first off, decide what is the target store WorkspaceInfo ws; if (workspace != null) { ws = catalog.getWorkspaceByName(workspace); if (ws == null) { throw new ProcessException("Could not find workspace " + workspace); } } else { ws = catalog.getDefaultWorkspace(); if (ws == null) { throw new ProcessException("The catalog is empty, could not find a default workspace"); } } // create a builder to help build catalog objects CatalogBuilder cb = new CatalogBuilder(catalog); cb.setWorkspace(ws); // ok, find the target store StoreInfo storeInfo = null; boolean add = false; if (store != null) { if (features != null) { storeInfo = catalog.getDataStoreByName(ws.getName(), store); } else if (coverage != null) { storeInfo = catalog.getCoverageStoreByName(ws.getName(), store); } if (storeInfo == null) { throw new ProcessException("Could not find store " + store + " in workspace " + workspace); // TODO: support store creation } } else if (features != null) { storeInfo = catalog.getDefaultDataStore(ws); if (storeInfo == null) { throw new ProcessException("Could not find a default store in workspace " + ws.getName()); } } else if (coverage != null) { // create a new coverage store LOGGER.info( "Auto-configuring coverage store: " + (name != null ? name : coverage.getName().toString())); storeInfo = cb.buildCoverageStore((name != null ? name : coverage.getName().toString())); add = true; store = (name != null ? name : coverage.getName().toString()); if (storeInfo == null) { throw new ProcessException("Could not find a default store in workspace " + ws.getName()); } } // check the target style if any StyleInfo targetStyle = null; if (styleName != null) { targetStyle = catalog.getStyleByName(styleName); if (targetStyle == null) { throw new ProcessException("Could not find style " + styleName); } } if (features != null) { // check if the target layer and the target feature type are not // already there (this is a half-assed attempt as we don't have // an API telling us how the feature type name will be changed // by DataStore.createSchema(...), but better than fully importing // the data into the target store to find out we cannot create the layer...) String tentativeTargetName = null; if (name != null) { tentativeTargetName = ws.getName() + ":" + name; } else { tentativeTargetName = ws.getName() + ":" + features.getSchema().getTypeName(); } if (catalog.getLayer(tentativeTargetName) != null) { throw new ProcessException("Target layer " + tentativeTargetName + " already exists"); } // check the target crs String targetSRSCode = null; if (srs != null) { try { Integer code = CRS.lookupEpsgCode(srs, true); if (code == null) { throw new WPSException("Could not find a EPSG code for " + srs); } targetSRSCode = "EPSG:" + code; } catch (Exception e) { throw new ProcessException("Could not lookup the EPSG code for the provided srs", e); } } else { // check we can extract a code from the original data GeometryDescriptor gd = features.getSchema().getGeometryDescriptor(); if (gd == null) { // data is geometryless, we need a fake SRS targetSRSCode = "EPSG:4326"; srsHandling = ProjectionPolicy.FORCE_DECLARED; } else { CoordinateReferenceSystem nativeCrs = gd.getCoordinateReferenceSystem(); if (nativeCrs == null) { throw new ProcessException( "The original data has no native CRS, " + "you need to specify the srs parameter"); } else { try { Integer code = CRS.lookupEpsgCode(nativeCrs, true); if (code == null) { throw new ProcessException( "Could not find an EPSG code for data " + "native spatial reference system: " + nativeCrs); } else { targetSRSCode = "EPSG:" + code; } } catch (Exception e) { throw new ProcessException( "Failed to loookup an official EPSG code for " + "the source data native " + "spatial reference system", e); } } } } // import the data into the target store SimpleFeatureType targetType; try { targetType = importDataIntoStore(features, name, (DataStoreInfo) storeInfo); } catch (IOException e) { throw new ProcessException("Failed to import data into the target store", e); } // now import the newly created layer into GeoServer try { cb.setStore(storeInfo); // build the typeInfo and set CRS if necessary FeatureTypeInfo typeInfo = cb.buildFeatureType(targetType.getName()); if (targetSRSCode != null) { typeInfo.setSRS(targetSRSCode); } if (srsHandling != null) { typeInfo.setProjectionPolicy(srsHandling); } // compute the bounds cb.setupBounds(typeInfo); // build the layer and set a style LayerInfo layerInfo = cb.buildLayer(typeInfo); if (targetStyle != null) { layerInfo.setDefaultStyle(targetStyle); } catalog.add(typeInfo); catalog.add(layerInfo); return layerInfo.prefixedName(); } catch (Exception e) { throw new ProcessException("Failed to complete the import inside the GeoServer catalog", e); } } else if (coverage != null) { try { final File directory = catalog.getResourceLoader().findOrCreateDirectory("data", workspace, store); final File file = File.createTempFile(store, ".tif", directory); ((CoverageStoreInfo) storeInfo).setURL(file.toURL().toExternalForm()); ((CoverageStoreInfo) storeInfo).setType("GeoTIFF"); // check the target crs CoordinateReferenceSystem cvCrs = coverage.getCoordinateReferenceSystem(); String targetSRSCode = null; if (srs != null) { try { Integer code = CRS.lookupEpsgCode(srs, true); if (code == null) { throw new WPSException("Could not find a EPSG code for " + srs); } targetSRSCode = "EPSG:" + code; } catch (Exception e) { throw new ProcessException("Could not lookup the EPSG code for the provided srs", e); } } else { // check we can extract a code from the original data if (cvCrs == null) { // data is geometryless, we need a fake SRS targetSRSCode = "EPSG:4326"; srsHandling = ProjectionPolicy.FORCE_DECLARED; srs = DefaultGeographicCRS.WGS84; } else { CoordinateReferenceSystem nativeCrs = cvCrs; if (nativeCrs == null) { throw new ProcessException( "The original data has no native CRS, " + "you need to specify the srs parameter"); } else { try { Integer code = CRS.lookupEpsgCode(nativeCrs, true); if (code == null) { throw new ProcessException( "Could not find an EPSG code for data " + "native spatial reference system: " + nativeCrs); } else { targetSRSCode = "EPSG:" + code; srs = CRS.decode(targetSRSCode, true); } } catch (Exception e) { throw new ProcessException( "Failed to loookup an official EPSG code for " + "the source data native " + "spatial reference system", e); } } } } MathTransform tx = CRS.findMathTransform(cvCrs, srs); if (!tx.isIdentity() || !CRS.equalsIgnoreMetadata(cvCrs, srs)) { coverage = WCSUtils.resample( coverage, cvCrs, srs, null, Interpolation.getInstance(Interpolation.INTERP_NEAREST)); } GeoTiffWriter writer = new GeoTiffWriter(file); // setting the write parameters for this geotiff final ParameterValueGroup params = new GeoTiffFormat().getWriteParameters(); params .parameter(AbstractGridFormat.GEOTOOLS_WRITE_PARAMS.getName().toString()) .setValue(DEFAULT_WRITE_PARAMS); final GeneralParameterValue[] wps = (GeneralParameterValue[]) params.values().toArray(new GeneralParameterValue[1]); try { writer.write(coverage, wps); } finally { try { writer.dispose(); } catch (Exception e) { // we tried, no need to fuss around this one } } // add or update the datastore info if (add) { catalog.add((CoverageStoreInfo) storeInfo); } else { catalog.save((CoverageStoreInfo) storeInfo); } cb.setStore((CoverageStoreInfo) storeInfo); AbstractGridCoverage2DReader reader = new GeoTiffReader(file); if (reader == null) { throw new ProcessException("Could not aquire reader for coverage."); } // coverage read params final Map customParameters = new HashMap(); /*String useJAIImageReadParam = "USE_JAI_IMAGEREAD"; if (useJAIImageReadParam != null) { customParameters.put(AbstractGridFormat.USE_JAI_IMAGEREAD.getName().toString(), Boolean.valueOf(useJAIImageReadParam)); }*/ CoverageInfo cinfo = cb.buildCoverage(reader, customParameters); // check if the name of the coverage was specified if (name != null) { cinfo.setName(name); } if (!add) { // update the existing CoverageInfo existing = catalog.getCoverageByCoverageStore( (CoverageStoreInfo) storeInfo, name != null ? name : coverage.getName().toString()); if (existing == null) { // grab the first if there is only one List<CoverageInfo> coverages = catalog.getCoveragesByCoverageStore((CoverageStoreInfo) storeInfo); if (coverages.size() == 1) { existing = coverages.get(0); } if (coverages.size() == 0) { // no coverages yet configured, change add flag and continue on add = true; } else { // multiple coverages, and one to configure not specified throw new ProcessException("Unable to determine coverage to configure."); } } if (existing != null) { cb.updateCoverage(existing, cinfo); catalog.save(existing); cinfo = existing; } } // do some post configuration, if srs is not known or unset, transform to 4326 if ("UNKNOWN".equals(cinfo.getSRS())) { // CoordinateReferenceSystem sourceCRS = // cinfo.getBoundingBox().getCoordinateReferenceSystem(); // CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326", true); // ReferencedEnvelope re = cinfo.getBoundingBox().transform(targetCRS, true); cinfo.setSRS("EPSG:4326"); // cinfo.setCRS( targetCRS ); // cinfo.setBoundingBox( re ); } // add/save if (add) { catalog.add(cinfo); LayerInfo layerInfo = cb.buildLayer(cinfo); if (styleName != null && targetStyle != null) { layerInfo.setDefaultStyle(targetStyle); } // JD: commenting this out, these sorts of edits should be handled // with a second PUT request on the created coverage /* String styleName = form.getFirstValue("style"); if ( styleName != null ) { StyleInfo style = catalog.getStyleByName( styleName ); if ( style != null ) { layerInfo.setDefaultStyle( style ); if ( !layerInfo.getStyles().contains( style ) ) { layerInfo.getStyles().add( style ); } } else { LOGGER.warning( "Client specified style '" + styleName + "'but no such style exists."); } } String path = form.getFirstValue( "path"); if ( path != null ) { layerInfo.setPath( path ); } */ boolean valid = true; try { if (!catalog.validate(layerInfo, true).isEmpty()) { valid = false; } } catch (Exception e) { valid = false; } layerInfo.setEnabled(valid); catalog.add(layerInfo); return layerInfo.prefixedName(); } else { catalog.save(cinfo); LayerInfo layerInfo = catalog.getLayerByName(cinfo.getName()); if (styleName != null && targetStyle != null) { layerInfo.setDefaultStyle(targetStyle); } return layerInfo.prefixedName(); } } catch (MalformedURLException e) { throw new ProcessException("URL Error", e); } catch (IOException e) { throw new ProcessException("I/O Exception", e); } catch (Exception e) { e.printStackTrace(); throw new ProcessException("Exception", e); } } return null; }