/* (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); } } }