/******************************************************************************* * Copyright (c) 2002, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Rational Software - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.core.model; import java.util.Enumeration; import org.eclipse.cdt.core.model.IBuffer; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IOpenable; import org.eclipse.cdt.internal.core.util.OverflowingLRUCache; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; /** * The buffer manager manages the set of open buffers. * It implements an LRU cache of buffers. * * This class is similar to the JDT BufferManager class */ public class BufferManager implements IBufferFactory { /** * An LRU cache of <code>IBuffers</code>. */ public class BufferCache<K> extends OverflowingLRUCache<K,IBuffer> { /** * Constructs a new buffer cache of the given size. */ public BufferCache(int size) { super(size); } /** * Constructs a new buffer cache of the given size. */ public BufferCache(int size, int overflow) { super(size, overflow); } /** * Returns true if the buffer is successfully closed and * removed from the cache, otherwise false. * * <p>NOTE: this triggers an external removal of this buffer * by closing the buffer. */ @Override protected boolean close(LRUCacheEntry<K,IBuffer> entry) { IBuffer buffer= entry._fValue; if (buffer.hasUnsavedChanges()) { return false; } buffer.close(); return true; } /** * Returns a new instance of the reciever. */ @Override protected OverflowingLRUCache<K, IBuffer> newInstance(int size, int overflow) { return new BufferCache<K>(size, overflow); } } protected static BufferManager DEFAULT_BUFFER_MANAGER; /** * LRU cache of buffers. The key and value for an entry * in the table is the identical buffer. */ protected OverflowingLRUCache<IOpenable, IBuffer> openBuffers = new BufferCache<IOpenable>(60); /** * Creates a new buffer manager. */ public BufferManager() { } /** * Adds a buffer to the table of open buffers. */ protected void addBuffer(IBuffer buffer) { openBuffers.put(buffer.getOwner(), buffer); } /** * @see org.eclipse.cdt.internal.core.model.IBufferFactory#createBuffer(org.eclipse.cdt.core.model.IOpenable) */ public IBuffer createBuffer(IOpenable owner) { ICElement element = (ICElement)owner; IResource resource = element.getResource(); return new Buffer( resource instanceof IFile ? (IFile)resource : null, owner, element.isReadOnly()); } /** * Returns the open buffer associated with the given owner, * or <code>null</code> if the owner does not have an open * buffer associated with it. */ public IBuffer getBuffer(IOpenable owner) { return (IBuffer)openBuffers.get(owner); } /** * Returns the default buffer factory. */ public IBufferFactory getDefaultBufferFactory() { return this; } /** * Returns the default buffer manager. */ public synchronized static BufferManager getDefaultBufferManager() { if (DEFAULT_BUFFER_MANAGER == null) { DEFAULT_BUFFER_MANAGER = new BufferManager(); } return DEFAULT_BUFFER_MANAGER; } /** * Returns an enumeration of all open buffers. * <p> * The <code>Enumeration</code> answered is thread safe. * * @see OverflowingLRUCache * @return Enumeration of IBuffer */ public Enumeration<IBuffer> getOpenBuffers() { synchronized (openBuffers) { openBuffers.shrink(); return openBuffers.elements(); } } /** * Removes a buffer from the table of open buffers. */ protected void removeBuffer(IBuffer buffer) { openBuffers.remove(buffer.getOwner()); } }