/* Copyright (c) 2001 - 2008 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.catalog;
import java.io.IOException;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geotools.util.logging.Logging;
/**
* Cascade deletes the visited objects, and modifies related object
* so that they are still consistent.
* In particular:
* <ul>
* <li>When removing a {@link LayerInfo} the {@link LayerGroupInfo} are modified
* by removing the layer. If the layer was the last one, the layer group
* is removed as well.
* </li>
* <li>When a {@link StyleInfo} is removed the layers using it as the default
* style are set with the default style, the layers that use is as an extra
* style are modified by removing it. Also, the layer groups using it
* are changed so that the default layer style is used in place of the
* one being removed
* </li>
*/
public class CascadeDeleteVisitor implements CatalogVisitor {
static final Logger LOGGER = Logging.getLogger(CascadeDeleteVisitor.class);
Catalog catalog;
public CascadeDeleteVisitor(Catalog catalog) {
this.catalog = catalog;
}
public void visit(Catalog catalog) {
}
public void visit(WorkspaceInfo workspace) {
// remove owned stores
for ( StoreInfo s : catalog.getStoresByWorkspace( workspace, StoreInfo.class ) ) {
s.accept(this);
}
//remove any linked namespaces
NamespaceInfo ns = catalog.getNamespaceByPrefix( workspace.getName() );
if ( ns != null ) {
ns.accept(this);
}
catalog.remove(workspace);
}
public void visit(NamespaceInfo workspace) {
catalog.remove(workspace);
}
void visitStore(StoreInfo store) {
// drill down into layers (into resources since we cannot scan layers)
List<ResourceInfo> resources = catalog.getResourcesByStore(store, ResourceInfo.class);
for (ResourceInfo ri : resources) {
List<LayerInfo> layers = catalog.getLayers(ri);
for (LayerInfo li : layers) {
li.accept(this);
}
}
catalog.remove(store);
}
public void visit(DataStoreInfo dataStore) {
visitStore(dataStore);
}
public void visit(CoverageStoreInfo coverageStore) {
visitStore(coverageStore);
}
public void visit(FeatureTypeInfo featureType) {
// when the resource/layer split is done, delete all layers linked to the resource
catalog.remove(featureType);
}
public void visit(CoverageInfo coverage) {
// when the resource/layer split is done, delete all layers linked to the resource
catalog.remove(coverage);
}
public void visit(LayerInfo layer) {
// first update the groups, remove the layer, and if no
// other layers remained, remove the group as well
for (LayerGroupInfo group : catalog.getLayerGroups()) {
if(group.getLayers().contains(layer)) {
// parallel remove of layer and styles
int index = group.getLayers().indexOf(layer);
group.getLayers().remove(index);
group.getStyles().remove(index);
// either update or remove the group
if(group.getLayers().size() == 0) {
catalog.remove(group);
} else {
catalog.save(group);
}
}
}
// remove the layer and (for the moment) its resource as well
// TODO: change this to just remove the resource once the
// resource/publish split is done
ResourceInfo resource = layer.getResource();
catalog.remove(layer);
catalog.remove(resource);
}
public void visit(StyleInfo style) {
// add users of this style among the related objects: layers
List<LayerInfo> layer = catalog.getLayers();
for (LayerInfo li : layer) {
// if it's the default style, reset it to the default one
if (li.getDefaultStyle().equals(style)) {
try {
li.setDefaultStyle(new CatalogBuilder(catalog).getDefaultStyle(li.getResource()));
catalog.save(li);
} catch(IOException e) {
// we fall back on the default style (since we cannot roll back the
// entire operation, no transactions in the catalog)
LOGGER.log(Level.WARNING, "Could not find default style for resource "
+ li.getResource() + " resetting the default to null");
li.setDefaultStyle(null);
}
}
// remove it also from the associated styles
if(li.getStyles().remove(style))
catalog.save(li);
}
// groups can also refer styles, reset each reference to the
// associated layer default style
List<LayerGroupInfo> groups = catalog.getLayerGroups();
for (LayerGroupInfo group : groups) {
List<StyleInfo> styles = group.getStyles();
boolean dirty = false;
for (int i = 0; i < styles.size(); i++) {
StyleInfo si = styles.get(i);
if(si != null && si.equals(style)) {
styles.set(i, group.getLayers().get(i).getDefaultStyle());
dirty = true;
}
}
if(dirty)
catalog.save(group);
}
// finally remove the style
catalog.remove(style);
}
public void visit(LayerGroupInfo layerGroup) {
catalog.remove(layerGroup);
}
}