/* (c) 2014 - 2016 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.io.Serializable; import java.lang.reflect.Method; import java.util.List; import org.geoserver.catalog.Catalog; import org.geoserver.catalog.CatalogInfo; import org.geoserver.catalog.LayerGroupInfo; import org.geoserver.catalog.LayerInfo; import org.geoserver.catalog.NamespaceInfo; import org.geoserver.catalog.StyleInfo; import org.geoserver.catalog.WorkspaceInfo; import org.geoserver.catalog.ValidationResult; import org.geoserver.catalog.util.CloseableIterator; import org.geoserver.catalog.util.CloseableIteratorAdapter; import org.geoserver.config.GeoServer; import org.geoserver.ows.LocalWorkspace; import org.geoserver.ows.LocalWorkspaceCatalogFilter; import org.geotools.feature.NameImpl; import org.opengis.feature.type.Name; import org.opengis.filter.Filter; import org.opengis.filter.sort.SortBy; import com.google.common.base.Function; /** * Catalog decorator handling cases when a {@link LocalWorkspace} is set. * <p> * This wrapper handles some additional cases that {@link LocalWorkspaceCatalogFilter} can not * handle by simple filtering. * </p> * @author Justin Deoliveira, OpenGeo * */ public class LocalWorkspaceCatalog extends AbstractCatalogDecorator implements Catalog { private GeoServer geoServer; public LocalWorkspaceCatalog(Catalog delegate) { super(delegate); } public void setGeoServer(GeoServer geoServer ) { this.geoServer = geoServer; } @Override public StyleInfo getStyleByName(String name) { if (LocalWorkspace.get() != null) { StyleInfo style = super.getStyleByName(LocalWorkspace.get(), name); if (style != null) { return style; } } return super.getStyleByName(name); } @Override public LayerInfo getLayer(String id) { return wrap(super.getLayer(id)); } @Override public LayerInfo getLayerByName(String name) { if (LocalWorkspace.get() != null) { String wsName = LocalWorkspace.get().getName(); //prefix the unqualified name if (name.contains(":")) { //name already prefixed, ensure it is prefixed with the correct one if (name.startsWith(wsName+":")) { //good to go, just pass call through return wrap(super.getLayerByName(name)); } else { //JD: perhaps strip of existing prefix? } } //prefix it explicitly NamespaceInfo ns = super.getNamespaceByPrefix(LocalWorkspace.get().getName()); LayerInfo layer = super.getLayerByName(new NameImpl(ns.getURI(), name)); return wrap(layer); } return super.getLayerByName(name); } @Override public LayerInfo getLayerByName(Name name) { if (LocalWorkspace.get() != null) { //if local workspace active drop the prefix return getLayerByName(name.getLocalPart()); } else { return super.getLayerByName(name); } } @Override public List<LayerInfo> getLayers() { if (useNameDequalifyingProxy()) { return NameDequalifyingProxy.createList(super.getLayers(), LayerInfo.class); } return super.getLayers(); } private boolean useNameDequalifyingProxy() { WorkspaceInfo workspaceInfo = LocalWorkspace.get(); boolean hidePrefix = geoServer == null || !geoServer.getSettings().isLocalWorkspaceIncludesPrefix(); boolean useNameDequalifyingProxy = workspaceInfo != null && hidePrefix; return useNameDequalifyingProxy; } @Override public void add(LayerInfo layer) { super.add(unwrap(layer)); } @Override public void save(LayerInfo layer) { super.save(unwrap(layer)); } @Override public void remove(LayerInfo layer) { super.remove(unwrap(layer)); } @Override public LayerInfo detach(LayerInfo layer) { return super.detach(unwrap(layer)); } @Override public ValidationResult validate(LayerInfo layer, boolean isNew) { return super.validate(unwrap(layer), isNew); } LayerInfo wrap(LayerInfo layer) { return wrap(layer, LayerInfo.class); } LayerInfo unwrap(LayerInfo layer) { return NameDequalifyingProxy.unwrap(layer); } @Override public LayerGroupInfo getLayerGroup(String id) { return wrap(super.getLayerGroup(id)); } @Override public LayerGroupInfo getLayerGroupByName(String name) { if (LocalWorkspace.get() != null) { LayerGroupInfo layerGroup = super.getLayerGroupByName(LocalWorkspace.get(), name); if (layerGroup != null) { return wrap(layerGroup); } // else fall back on unqualified lookup } return wrap(super.getLayerGroupByName(name)); } /* * check that the layer group workspace matches the */ LayerGroupInfo check(LayerGroupInfo layerGroup) { if (LocalWorkspace.get() != null) { if (layerGroup.getWorkspace() != null && !LocalWorkspace.get().equals(layerGroup.getWorkspace())) { return null; } } return layerGroup; } @Override public LayerGroupInfo getLayerGroupByName(String workspaceName, String name) { return wrap(super.getLayerGroupByName(workspaceName, name)); } @Override public LayerGroupInfo getLayerGroupByName(WorkspaceInfo workspace, String name) { return wrap(super.getLayerGroupByName(workspace, name)); } @Override public List<LayerGroupInfo> getLayerGroups() { return wrap(super.getLayerGroups()); } @Override public List<LayerGroupInfo> getLayerGroupsByWorkspace(String workspaceName) { return wrap(super.getLayerGroupsByWorkspace(workspaceName)); } @Override public List<LayerGroupInfo> getLayerGroupsByWorkspace( WorkspaceInfo workspace) { return wrap(super.getLayerGroupsByWorkspace(workspace)); } public void add(LayerGroupInfo layerGroup) { super.add(unwrap(layerGroup)); } public void save(LayerGroupInfo layerGroup) { super.save(unwrap(layerGroup)); } public void remove(LayerGroupInfo layerGroup) { super.remove(unwrap(layerGroup)); } public LayerGroupInfo detach(LayerGroupInfo layerGroup) { return super.detach(unwrap(layerGroup)); } public ValidationResult validate(LayerGroupInfo layerGroup, boolean isNew) { return super.validate(unwrap(layerGroup), isNew); } LayerGroupInfo wrap(LayerGroupInfo layerGroup) { return wrap(layerGroup, LayerGroupInfo.class); } <T> T wrap(T obj, Class<T> clazz) { if (obj == null) { return null; } if (useNameDequalifyingProxy()) { return NameDequalifyingProxy.create(obj, clazz); } return obj; } <T> T unwrap(T obj) { return NameDequalifyingProxy.unwrap(obj); } List<LayerGroupInfo> wrap(List<LayerGroupInfo> layerGroups) { if (useNameDequalifyingProxy()) { return NameDequalifyingProxy.createList(layerGroups, LayerGroupInfo.class); } return layerGroups; } static class NameDequalifyingProxy implements WrappingProxy, Serializable { Object object; NameDequalifyingProxy(Object object) { this.object = object; } public Object getProxyObject() { return object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("prefixedName".equals(method.getName()) || "getPrefixedName".equals(method.getName()) || "getName".equals(method.getName())) { String val = (String) method.invoke(object, args); if (val == null || val.indexOf(':') == -1) { return val; } return val.split(":")[1]; } return method.invoke(object, args); } public static <T> T create( T object, Class<T> clazz) { return ProxyUtils.createProxy(object, clazz, new NameDequalifyingProxy(object)); } public static <T> List<T> createList(List<T> object, Class<T> clazz) { return new ProxyList(object, clazz) { @Override protected <T> T createProxy(T proxyObject, Class<T> proxyInterface) { return create(proxyObject, proxyInterface); } @Override protected <T> T unwrapProxy(T proxy, Class<T> proxyInterface) { return unwrap(proxy); } }; } public static <T> T unwrap( T object ) { return ProxyUtils.unwrap(object, NameDequalifyingProxy.class); } } @Override public <T extends CatalogInfo> int count(Class<T> of, Filter filter) { return delegate.count(of, filter); } @Override public <T extends CatalogInfo> T get(Class<T> type, Filter filter) throws IllegalArgumentException { return wrap(delegate.get(type, filter), type); } @Override public <T extends CatalogInfo> CloseableIterator<T> list(Class<T> of, Filter filter) { return list(of, filter, (Integer) null, (Integer) null, (SortBy) null); } /** * Returns a decorating iterator over the one returned by the delegate that wraps every object * it returns, if possible. * * @see #wrap(Object, Class) * @see org.geoserver.catalog.Catalog#list(java.lang.Class, org.geoserver.catalog.Predicate, * java.lang.Integer, java.lang.Integer, org.geoserver.catalog.OrderBy) */ @Override public <T extends CatalogInfo> CloseableIterator<T> list(final Class<T> of, final Filter filter, final Integer offset, final Integer count, final SortBy sortBy) { CloseableIterator<T> iterator = delegate.list(of, filter, offset, count, sortBy); Function<T, T> wrappingFunction = new Function<T, T>() { final Class<T> type = of; @Override public T apply(T catalogObject) { return wrap(catalogObject, type); } }; return CloseableIteratorAdapter.transform(iterator, wrappingFunction); } public void removeListeners(Class listenerClass) { delegate.removeListeners(listenerClass); } @Override public NamespaceInfo getDefaultNamespace() { if (LocalWorkspace.get() != null) { WorkspaceInfo ws = LocalWorkspace.get(); NamespaceInfo ns = delegate.getNamespaceByPrefix(ws.getName()); if(ns != null) { return ns; } } return super.getDefaultNamespace(); } @Override public WorkspaceInfo getDefaultWorkspace() { if (LocalWorkspace.get() != null) { return LocalWorkspace.get(); } return super.getDefaultWorkspace(); } }