Skip to content

Commit

Permalink
Merge pull request #2052 from mattkrusz/GEOS-7855-css-styles-missing
Browse files Browse the repository at this point in the history
[GEOS-7855] Fix for new style editor thinking old CSS styles are SLD
  • Loading branch information
tbarsballe committed Jan 16, 2017
2 parents 7fefbe8 + c97a434 commit c9bad08
Show file tree
Hide file tree
Showing 13 changed files with 351 additions and 2 deletions.
6 changes: 6 additions & 0 deletions src/web/wms/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@
<groupId>org.geotools</groupId>
<artifactId>gt-data</artifactId>
</dependency>
<dependency>
<groupId>org.geoserver.extension</groupId>
<artifactId>gs-css</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import org.apache.wicket.extensions.markup.html.tabs.ITab;
import org.apache.wicket.extensions.markup.html.tabs.PanelCachingTab;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Panel;
Expand All @@ -46,6 +45,8 @@
import org.geoserver.catalog.Styles;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.catalog.impl.LayerInfoImpl;
import org.geoserver.config.GeoServerDataDirectory;
import org.geoserver.platform.resource.Resource;
import org.geoserver.web.ComponentAuthorizer;
import org.geoserver.web.GeoServerApplication;
import org.geoserver.web.GeoServerSecuredPage;
Expand Down Expand Up @@ -82,6 +83,7 @@ public AbstractStylePage() {
}

public AbstractStylePage(StyleInfo style) {
recoverCssStyle(style);
initPreviewLayer(style);
initUI(style);
}
Expand Down Expand Up @@ -430,7 +432,61 @@ public void setRawStyle(Reader in) throws IOException {
editor.setModelObject(rawStyle);
in.close();
}


/**
* Check for an original CSS version of the style created by the old CSS extension (pre-pluggable styles). If a CSS style is found, recover it if
* the derived SLD has not subsequently been manually edited.
*
* The recovery is accomplished by updating the catalog to point to the original CSS file, and changing the style's format to "css".
*
* @param si The {@link StyleInfo} for which to check for and potentially recover a CSS version.
*/
protected void recoverCssStyle(StyleInfo si) {
if (si == null) {
return;
}

// Only try to repair missing CSS files if a CSS style handler is registered.
try {
Styles.handler("css");
} catch (Exception e) {
return;
}

// Use this tolerance to prevent erasing an SLD that was manually edited after being
// generated from a CSS file. (Generated SLDs will always be newer than the CSS).
long favorSLDIfNewerByMS = 600000;

// The problem only exists for styles with an "sld" format (either explicitly or by default).
if ("sld".equalsIgnoreCase(si.getFormat())) {
String filename = si.getFilename();
String filenameCss = filename.substring(0, filename.lastIndexOf('.')) + ".css";
GeoServerDataDirectory dataDir = new GeoServerDataDirectory(
getCatalog().getResourceLoader());
Resource cssResource = dataDir.get(si, filenameCss);

if (!cssResource.getType().equals(Resource.Type.UNDEFINED)) {
// If there is an existing CSS file with the style's name, check if it should be recovered.
Resource sldResource = dataDir.get(si, filename);
long sldNewerByMs = sldResource.lastmodified() - cssResource.lastmodified();

if (sldNewerByMs > favorSLDIfNewerByMS) {
LOGGER.log(Level.WARNING,
"A CSS version of " + si.getName() + " has been recovered ("
+ filenameCss + "), but the SLD is more recent by "
+ sldNewerByMs + " ms. The style will be left as an SLD.");
} else {
LOGGER.log(Level.WARNING,
"A CSS version of " + si.getName() + " has been recovered ("
+ filenameCss + "). The style will be converted to CSS.");
si.setFilename(filenameCss);
si.setFormat("css");
getCatalog().save(si);
}
}
}
}

/**
* Called when a configuration change requires updating an inactive tab
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public StyleEditPage(PageParameters parameters) {
doReturn(StylePage.class);
return;
}

recoverCssStyle(si);
initPreviewLayer(si);
initUI(si);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.wms.web.data;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.geoserver.catalog.Catalog;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.Styles;
import org.geoserver.data.test.SystemTestData;
import org.geoserver.web.GeoServerWicketTestSupport;
import org.junit.Before;
import org.junit.Test;

/**
* Tests for recovering CSS styles generated by the old (pre-pluggable styles) CSS extension. That extension extension output styles based on
* generated SLD files, without saving a reference to the user's CSS input, and as a result the new style editor treats them as SLD.
*
*/
public class StyleEditCssRecoveryTest extends GeoServerWicketTestSupport {

String oldCssStyle = "OldCssStyle";

String oldCssStyleWithFormatSLD = "OldCssStyle_Format_Set_To_SLD";

String oldCssStyleWithSLDManuallyEdited = "OldCssStyle_SLD_Manually_Edited";

Catalog catalog;

protected void setUpTestData(SystemTestData testData) throws Exception {
super.setUpTestData(testData);
System.out.println("setUpTestData()");

Date t0 = new Date(1483228800000L); // Midnight Jan 1, 2017 UTC
List<String> testStyleNames = Arrays.asList(oldCssStyle, oldCssStyleWithFormatSLD,
oldCssStyleWithSLDManuallyEdited);

for (String styleName : testStyleNames) {
for (String ext : Arrays.asList(".css", ".sld", ".xml")) {
testData.copyTo(this.getClass().getResourceAsStream(styleName + ext),
"styles/" + styleName + ext);
File f = Paths.get(testData.getDataDirectoryRoot().getAbsolutePath(),
"styles/" + styleName + ext).toFile();
f.setLastModified(t0.getTime());
}
}

// Make this SLD file appear as if it was edited after being generated from CSS.
File manuallyEditedSld = Paths.get(testData.getDataDirectoryRoot().getAbsolutePath(),
"styles/" + oldCssStyleWithSLDManuallyEdited + ".sld").toFile();
manuallyEditedSld.setLastModified(t0.getTime() + 1000000L);
}

@Override
protected void onSetUp(SystemTestData testData) throws Exception {
super.onSetUp(testData);
}

@Before
public void setUp() throws Exception {
login();
catalog = getCatalog();
}

/**
* Test recovery of a CSS Style generated by the old CSS Extension, when the StyleInfo has no declared <format> and its filename points to a
* derived SLD.
*/
@Test
public void testRecoverLostCssStyle() throws Exception {
StyleInfo styleInfo = catalog.getStyleByName(oldCssStyle);
StyleEditPage edit = new StyleEditPage(styleInfo);

tester.startPage(edit);
tester.assertRenderedPage(StyleEditPage.class);
tester.assertNoErrorMessage();

// Assert that the page displays the format as css
tester.assertModelValue("styleForm:context:panel:format", "css");

// Assert that the editor text area contains css
String editorContents = (String) tester
.getComponentFromLastRenderedPage(
"styleForm:styleEditor:editorContainer:editorParent:editor")
.getDefaultModelObject();
Styles.handler("css").parse(editorContents, null, null, null);

// Assert that the catalog's StyleInfo is now a css style
StyleInfo si = catalog.getStyleByName(oldCssStyle);
assertEquals("css", si.getFormat());
assertEquals(oldCssStyle + ".css", si.getFilename());

}

/**
* Test recovery of a CSS Style generated by the old CSS Extension, when the StyleInfo declares <format>sld</format> and its filename points to a
* derived SLD.
*/
@Test
public void testRecoverLostCssStyleWithFormatSetToSLD() throws Exception {
StyleInfo styleInfo = catalog.getStyleByName(oldCssStyleWithFormatSLD);
StyleEditPage edit = new StyleEditPage(styleInfo);

tester.startPage(edit);
tester.assertRenderedPage(StyleEditPage.class);
tester.assertNoErrorMessage();

// Assert that the page displays the format as css
tester.assertModelValue("styleForm:context:panel:format", "css");

// Assert that the editor text area contains css
String editorContents = (String) tester
.getComponentFromLastRenderedPage(
"styleForm:styleEditor:editorContainer:editorParent:editor")
.getDefaultModelObject();
Styles.handler("css").parse(editorContents, null, null, null);

// Assert that the catalog's StyleInfo is now a css style
StyleInfo si = catalog.getStyleByName(oldCssStyleWithFormatSLD);
assertEquals("css", si.getFormat());
assertEquals(oldCssStyleWithFormatSLD + ".css", si.getFilename());
}

/**
* Test that the recovery code does not overwrite generated SLD styles if they were subsequently edited.
*/
@Test
public void testIgnoreCssStyleIfSLDWasEdited() throws Exception {
StyleInfo styleInfo = catalog.getStyleByName(oldCssStyleWithSLDManuallyEdited);
StyleEditPage edit = new StyleEditPage(styleInfo);

tester.startPage(edit);
tester.assertRenderedPage(StyleEditPage.class);
tester.assertNoErrorMessage();

// Assert that the page displays the format as SLD
tester.assertModelValue("styleForm:context:panel:format", "sld");

// Assert that the editor text area contains SLD
String editorContents = (String) tester
.getComponentFromLastRenderedPage(
"styleForm:styleEditor:editorContainer:editorParent:editor")
.getDefaultModelObject();
Styles.handler("sld").parse(editorContents, null, null, null);

// Assert that the catalog's StyleInfo is still a SLD style
StyleInfo si = catalog.getStyleByName(oldCssStyleWithSLDManuallyEdited);
assertEquals("sld", si.getFormat());
assertEquals(oldCssStyleWithSLDManuallyEdited + ".sld", si.getFilename());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[VTOTAL > 100] {
fill: #0000FF;
fill-opacity: 0.7;
stroke: #000000;
stroke-width: 0.5;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<sld:UserStyle xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc">
<sld:Name>Default Styler</sld:Name>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<ogc:Filter>
<ogc:PropertyIsGreaterThan>
<ogc:PropertyName>VTOTAL</ogc:PropertyName>
<ogc:Literal>100</ogc:Literal>
</ogc:PropertyIsGreaterThan>
</ogc:Filter>
<sld:PolygonSymbolizer>
<sld:Fill>
<sld:CssParameter name="fill">#0000FF</sld:CssParameter>
<sld:CssParameter name="fill-opacity">0.699999988079071</sld:CssParameter>
</sld:Fill>
</sld:PolygonSymbolizer>
<sld:LineSymbolizer>
<sld:Stroke>
<sld:CssParameter name="stroke-width">0.5</sld:CssParameter>
</sld:Stroke>
</sld:LineSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<style>
<id>StyleInfoImpl--b5f628e:1598a2fe470:-8000</id>
<name>OldCssStyle</name>
<sldVersion>
<version>1.0.0</version>
</sldVersion>
<filename>OldCssStyle.sld</filename>
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[VTOTAL > 100] {
fill: #0000FF;
fill-opacity: 0.7;
stroke: #000000;
stroke-width: 0.5;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<sld:UserStyle xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc">
<sld:Name>Default Styler</sld:Name>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<ogc:Filter>
<ogc:PropertyIsGreaterThan>
<ogc:PropertyName>VTOTAL</ogc:PropertyName>
<ogc:Literal>100</ogc:Literal>
</ogc:PropertyIsGreaterThan>
</ogc:Filter>
<sld:PolygonSymbolizer>
<sld:Fill>
<sld:CssParameter name="fill">#0000FF</sld:CssParameter>
<sld:CssParameter name="fill-opacity">0.699999988079071</sld:CssParameter>
</sld:Fill>
</sld:PolygonSymbolizer>
<sld:LineSymbolizer>
<sld:Stroke>
<sld:CssParameter name="stroke-width">0.5</sld:CssParameter>
</sld:Stroke>
</sld:LineSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<style>
<id>StyleInfoImpl--b5f628e:1598a2fe470:-7ffc</id>
<name>OldCssStyle_Format_Set_To_SLD</name>
<sldVersion>
<version>1.0.0</version>
</sldVersion>
<filename>OldCssStyle_Format_Set_To_SLD.sld</filename>
<format>sld</format>
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[VTOTAL > 100] {
fill: #0000FF;
fill-opacity: 0.7;
stroke: #000000;
stroke-width: 0.5;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<sld:UserStyle xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:gml="http://www.opengis.net/gml" xmlns:ogc="http://www.opengis.net/ogc">
<sld:Name>Default Styler</sld:Name>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<ogc:Filter>
<ogc:PropertyIsGreaterThan>
<ogc:PropertyName>VTOTAL</ogc:PropertyName>
<ogc:Literal>100</ogc:Literal>
</ogc:PropertyIsGreaterThan>
</ogc:Filter>
<sld:PolygonSymbolizer>
<sld:Fill>
<sld:CssParameter name="fill">#00FF00</sld:CssParameter>
<sld:CssParameter name="fill-opacity">0.699999988079071</sld:CssParameter>
</sld:Fill>
</sld:PolygonSymbolizer>
<sld:LineSymbolizer>
<sld:Stroke>
<sld:CssParameter name="stroke-width">0.5</sld:CssParameter>
</sld:Stroke>
</sld:LineSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
Loading

0 comments on commit c9bad08

Please sign in to comment.