/* Copyright (c) 2001 - 2011 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.web; import org.apache.wicket.IRequestTarget; import org.apache.wicket.Page; import org.apache.wicket.request.target.component.IBookmarkablePageRequestTarget; import org.apache.wicket.request.target.component.IPageRequestTarget; import org.geoserver.GeoServerConfigurationLock; import org.geoserver.GeoServerConfigurationLock.LockType; /** * Protects the catalog and configuration from concurrent access from the web GUI side (will stay * here until the catalog and configution will become thread safe). * <p> * It locks in write mode all {@link GeoServerSecuredPage} subclasses, as those have some * possibility to write on the configuration/catalog, all other pages are locked in read mode. * * @author Andrea Aime - GeoSolutions * */ public class WicketConfigurationLockCallback implements WicketCallback { GeoServerConfigurationLock locker; static ThreadLocal<LockType> THREAD_LOCK = new ThreadLocal<GeoServerConfigurationLock.LockType>(); public WicketConfigurationLockCallback(GeoServerConfigurationLock locker) { this.locker = locker; } @Override public void onBeginRequest() { // nothing to do here } @Override public void onAfterTargetsDetached() { // who cares? } @Override public void onEndRequest() { LockType type = THREAD_LOCK.get(); if (type != null) { THREAD_LOCK.remove(); locker.unlock(type); } } @Override public void onRequestTargetSet(IRequestTarget target) { // we can have many of these calls per http call, avoid locking multiple times, // onEndRequest will be called just once LockType type = THREAD_LOCK.get(); if (type != null) { return; } // setup a write lock for secured pages, a read one for the others if (target instanceof IPageRequestTarget) { IPageRequestTarget pt = (IPageRequestTarget) target; Page page = pt.getPage(); if (page instanceof GeoServerSecuredPage) { type = LockType.WRITE; } } else if (target instanceof IBookmarkablePageRequestTarget) { IBookmarkablePageRequestTarget bt = (IBookmarkablePageRequestTarget) target; if (GeoServerSecuredPage.class.isAssignableFrom(bt.getPageClass())) { type = LockType.WRITE; } } if (type == null) { type = LockType.READ; } // and lock THREAD_LOCK.set(type); locker.lock(type); } @Override public void onRuntimeException(Page page, RuntimeException e) { // nothing to do } }