/*==========================================================================*\ | $Id: WCSharedEC.java,v 1.1 2011/12/25 02:24:54 stedwar2 Exp $ |*-------------------------------------------------------------------------*| | Copyright (C) 2011 Virginia Tech | | This file is part of Web-CAT. | | Web-CAT is free software; you can redistribute it and/or modify | it under the terms of the GNU Affero General Public License as published | by the Free Software Foundation; either version 3 of the License, or | (at your option) any later version. | | Web-CAT is distributed in the hope that it will be useful, | but WITHOUT ANY WARRANTY; without even the implied warranty of | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | GNU General Public License for more details. | | You should have received a copy of the GNU Affero General Public License | along with Web-CAT; if not, see <http://www.gnu.org/licenses/>. \*==========================================================================*/ package org.webcat.woextensions; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import com.webobjects.eocontrol.EOEnterpriseObject; import com.webobjects.eocontrol.EOObjectStore; import com.webobjects.eocontrol.EOSharedEditingContext; // ------------------------------------------------------------------------- /** * This is a specialized shared editing context that enforces read-only * access. * * @author Stephen Edwards * @author Last changed by $Author: stedwar2 $ * @version $Revision: 1.1 $, $Date: 2011/12/25 02:24:54 $ */ public class WCSharedEC extends EOSharedEditingContext { //~ Constructors .......................................................... // ---------------------------------------------------------- /** * Creates a new object. */ public WCSharedEC() { this(defaultParentObjectStore()); } // ---------------------------------------------------------- /** * Creates a new object. * @param os the parent object store */ public WCSharedEC(EOObjectStore os) { super(os); setDelegate(WCEC.factory().defaultEditingContextDelegate()); if (log.isDebugEnabled()) { log.debug("creating " + getClass().getSimpleName() + " with parent object store " + os + "; " + this + "; by " + Thread.currentThread() + "; at " + System.currentTimeMillis()); } } // ---------------------------------------------------------- /** * Installs an instance of this class as the default shared * editing context for the application. */ public static void install() { EOSharedEditingContext.setDefaultSharedEditingContext( new WCSharedEC()); } //~ Methods ............................................................... // ---------------------------------------------------------- @Override public void lock() { String message = null; if (log.isDebugEnabled()) { synchronized (this) { message = "shared EC; " + this + "; by " + Thread.currentThread() + "; at " + System.currentTimeMillis(); log.debug("lock() attempt; " + message , new Exception("from here")); if (owners == null) { initDebugFields(); } else if (owners.size() > 0 && owners.get(owners.size() - 1) != Thread.currentThread()) { log.warn("This shared editing context is already " + "locked by another thread! Owners = " + owners); String dump = "Existing locks from = " + lockLocations.size(); for (String msg : lockLocations) { dump += "\n" + msg; } log.warn(dump); } } } super.lock(); if (log.isDebugEnabled()) { synchronized (this) { if (writer == null) { initDebugFields(); } writer.getBuffer().setLength(0); message = "lock() acquired; " + message; new Exception(message).printStackTrace(out); lockLocations.add(writer.toString()); owners.add(Thread.currentThread()); log.debug(message); } } } // ---------------------------------------------------------- @Override public boolean tryLock() { String message = null; if (log.isDebugEnabled()) { synchronized (this) { message = "shared EC; " + this + "; by " + Thread.currentThread() + "; at " + System.currentTimeMillis(); log.debug("tryLock() attempt; " + message , new Exception("from here")); } } boolean result = super.tryLock(); if (log.isDebugEnabled()) { synchronized (this) { if (result) { if (writer == null) { initDebugFields(); } writer.getBuffer().setLength(0); message = "tryLock() acquired; " + message; new Exception(message).printStackTrace(out); lockLocations.add(writer.toString()); owners.add(Thread.currentThread()); log.debug(message); } else { log.debug("tryLock() failed; " + message); } } } return result; } // ---------------------------------------------------------- @Override public void insertObject(EOEnterpriseObject object) { throw new UnsupportedOperationException( getClass().getSimpleName() + " is READ ONLY!", new Exception("called from here")); } // ---------------------------------------------------------- @Override public void deleteObject(EOEnterpriseObject object) { throw new UnsupportedOperationException( getClass().getSimpleName() + " is READ ONLY!", new Exception("called from here")); } // ---------------------------------------------------------- @Override public void saveChanges() { throw new UnsupportedOperationException( getClass().getSimpleName() + " is READ ONLY!", new Exception("called from here")); } // ---------------------------------------------------------- @Override public void unlock() { super.unlock(); if (log.isDebugEnabled()) { synchronized (this) { log.debug("unlock(); shared EC; " + this + "; by " + Thread.currentThread() + "; at " + System.currentTimeMillis() // , new Exception("from here") ); if (lockLocations == null) { initDebugFields(); } else if (lockLocations.size() > 0) { lockLocations.remove(lockLocations.size() - 1); owners.remove(owners.size() - 1); } else { log.error("no lock location to pop!"); } } } } // ---------------------------------------------------------- @Override public void dispose() { if (log.isDebugEnabled()) { log.debug("dispose(): " + this); } super.dispose(); } // ---------------------------------------------------------- private void initDebugFields() { lockLocations = new ArrayList<String>(16); owners = new ArrayList<Thread>(16); writer = new StringWriter(); out = new PrintWriter(writer); } //~ Instance/static variables ............................................. private List<String> lockLocations = null; private List<Thread> owners = null; private StringWriter writer = null; private PrintWriter out = null; static Logger log = Logger.getLogger(WCSharedEC.class); }