/* (c) 2016 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.catalog; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import org.geoserver.GeoServerConfigurationLock; import org.geoserver.GeoServerConfigurationLock.LockType; import org.geoserver.catalog.impl.ProxyUtils; import org.geoserver.catalog.impl.WrappingProxy; /** * Performs lock upgrades on the fly * * @author Andrea Aime - GeoSolutions */ public class LockingCatalogFacade implements InvocationHandler, WrappingProxy { GeoServerConfigurationLock configurationLock; CatalogFacade delegate; public LockingCatalogFacade(CatalogFacade delegate, GeoServerConfigurationLock configurationLock) { this.configurationLock = configurationLock; this.delegate = delegate; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { LockType lockType = configurationLock.getCurrentLock(); if (lockType == LockType.READ && isWriteMethod(method)) { configurationLock.tryUpgradeLock(); } return method.invoke(delegate, args); } private boolean isWriteMethod(Method method) { final String name = method.getName(); // ignoring setCatalog because it does not actually happens during return name.startsWith("set") || name.startsWith("remove") || name.startsWith("add") || name.startsWith("save"); } /** * Returns a wrapped {@link CatalogFacade} that will upgrade read locks to write before attempting any write operation * * @param facade * @param configurationLock * @return */ public static CatalogFacade create(CatalogFacade facade, GeoServerConfigurationLock configurationLock) { return ProxyUtils.createProxy(facade, CatalogFacade.class, new LockingCatalogFacade(facade, configurationLock)); } @Override public Object getProxyObject() { return delegate; } }