/* (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.catalog.impl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.server.UID;
import java.util.LinkedHashSet;
import java.util.List;
import org.geoserver.catalog.CatalogFacade;
import org.geoserver.catalog.CatalogInfo;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.MapInfo;
import org.geoserver.catalog.NamespaceInfo;
import org.geoserver.catalog.PublishedInfo;
import org.geoserver.catalog.ResourceInfo;
import org.geoserver.catalog.StoreInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.catalog.WorkspaceInfo;
import org.geoserver.ows.util.OwsUtils;
public abstract class AbstractCatalogFacade implements CatalogFacade {
public static final WorkspaceInfo _ANY_WORKSPACE = any(WorkspaceInfo.class);
public static final NamespaceInfo _ANY_NAMESPACE = any(NamespaceInfo.class);
public static final WorkspaceInfo _NO_WORKSPACE = any(WorkspaceInfo.class);
@SuppressWarnings("unchecked")
static <T extends CatalogInfo> T any(Class<T> clazz) {
Class proxyClass = Proxy.getProxyClass(clazz.getClassLoader(), clazz);
try {
return (T) proxyClass.getConstructor(new Class[] { InvocationHandler.class })
.newInstance(new Object[] { new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
} });
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//
// Utilities
//
public static <T> T unwrap(T obj) {
return ModificationProxy.unwrap(obj);
}
/**
* @deprecated use {@link #beforeSaved(CatalogInfo, List, List, List)} and {@link #afterSaved(CatalogInfo, List, List, List)} as
* appropriate
*/
@Deprecated
protected void saved(CatalogInfo object) {
// this object is a proxy
ModificationProxy h = (ModificationProxy) Proxy.getInvocationHandler(object);
// fire out what changed
List propertyNames = h.getPropertyNames();
List newValues = h.getNewValues();
List oldValues = h.getOldValues();
beforeSaved(object, propertyNames, oldValues, newValues);
commitProxy(object);
afterSaved(object, propertyNames, oldValues, newValues);
}
protected void beforeSaved(CatalogInfo object, List propertyNames, List oldValues, List newValues) {
CatalogInfo real = ModificationProxy.unwrap(object);
// TODO: protect this original object, perhaps with another proxy
getCatalog().fireModified(real, propertyNames, oldValues, newValues);
}
protected <T extends CatalogInfo> T commitProxy(T object){
// this object is a proxy
ModificationProxy h = (ModificationProxy) Proxy.getInvocationHandler(object);
// get the real object
T real = (T) h.getProxyObject();
// commit to the original object
h.commit();
return real;
}
protected void afterSaved(CatalogInfo object, List propertyNames, List oldValues, List newValues) {
CatalogInfo real = ModificationProxy.unwrap(object);
// fire the post modify event
getCatalog().firePostModified(real, propertyNames, oldValues, newValues);
}
protected void resolve(LayerInfo layer) {
setId(layer);
ResourceInfo resource = ResolvingProxy.resolve(getCatalog(), layer.getResource());
if (resource != null) {
resource = unwrap(resource);
layer.setResource(resource);
}
StyleInfo style = ResolvingProxy.resolve(getCatalog(), layer.getDefaultStyle());
if (style != null) {
style = unwrap(style);
layer.setDefaultStyle(style);
}
LinkedHashSet<StyleInfo> styles = new LinkedHashSet<StyleInfo>();
for (StyleInfo s : layer.getStyles()) {
s = ResolvingProxy.resolve(getCatalog(), s);
s = unwrap(s);
styles.add(s);
}
((LayerInfoImpl) layer).setStyles(styles);
}
protected void resolve(LayerGroupInfo layerGroup) {
setId(layerGroup);
LayerGroupInfoImpl lg = (LayerGroupInfoImpl) layerGroup;
for (int i = 0; i < lg.getLayers().size(); i++) {
PublishedInfo l = lg.getLayers().get(i);
PublishedInfo resolved;
if (l instanceof LayerGroupInfo) {
resolved = unwrap(ResolvingProxy.resolve(getCatalog(), (LayerGroupInfo) l));
} else {
resolved = unwrap(ResolvingProxy.resolve(getCatalog(), (LayerInfo) l));
}
lg.getLayers().set(i, resolved != null ? resolved : l);
}
for (int i = 0; i < lg.getStyles().size(); i++) {
StyleInfo s = lg.getStyles().get(i);
if (s != null) {
StyleInfo resolved = unwrap(ResolvingProxy.resolve(getCatalog(), s));
lg.getStyles().set(i, resolved);
}
}
}
protected void resolve(StyleInfo style) {
setId(style);
}
protected void resolve(MapInfo map) {
setId(map);
}
protected void resolve(WorkspaceInfo workspace) {
setId(workspace);
}
protected void resolve(NamespaceInfo namespace) {
setId(namespace);
}
protected void resolve(StoreInfo store) {
setId(store);
StoreInfoImpl s = (StoreInfoImpl) store;
// resolve the workspace
WorkspaceInfo resolved = ResolvingProxy.resolve(getCatalog(), s.getWorkspace());
if (resolved != null) {
resolved = unwrap(resolved);
s.setWorkspace(resolved);
} else {
// this means the workspace has not yet been added to the catalog, keep the proxy around
System.out.println("this means the workspace has not yet been added to the catalog, keep the proxy around");
}
}
protected void resolve(ResourceInfo resource) {
setId(resource);
ResourceInfoImpl r = (ResourceInfoImpl) resource;
// resolve the store
StoreInfo store = ResolvingProxy.resolve(getCatalog(), r.getStore());
if (store != null) {
store = unwrap(store);
r.setStore(store);
}
// resolve the namespace
NamespaceInfo namespace = ResolvingProxy.resolve(getCatalog(), r.getNamespace());
if (namespace != null) {
namespace = unwrap(namespace);
r.setNamespace(namespace);
}
}
protected void setId(Object o) {
if (OwsUtils.get(o, "id") == null) {
String uid = new UID().toString();
OwsUtils.set(o, "id", o.getClass().getSimpleName() + "-" + uid);
}
}
}