// BEGIN LICENSE BLOCK // Version: CMPL 1.1 // // The contents of this file are subject to the Cisco-style Mozilla Public // License Version 1.1 (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License // at www.eclipse-clp.org/license. // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See // the License for the specific language governing rights and limitations // under the License. // // The Original Code is The ECLiPSe Constraint Logic Programming System. // The Initial Developer of the Original Code is Cisco Systems, Inc. // Portions created by the Initial Developer are // Copyright (C) 2006 Cisco Systems, Inc. All Rights Reserved. // // Contributor(s): // // END LICENSE BLOCK package com.parctechnologies.eclipse.visualisation; import java.util.*; import java.beans.*; import javax.swing.table.*; import com.parctechnologies.eclipse.*; /** * A SparseViewletStore is a recursive data structure intended to * mirror the number, size and fixity of the dimensions of a certain * elements within a viewable on the eclipse side. * *
Instead of viewable elements, it contains viewlet data. Each * viewlet is produced from a ViewletFactory. * *
Note that ViewletArray is not responsible for maintaining
* location names, only for keeping references to them and providing
* access to them.
* */
public class SparseViewletStore extends AbstractViewletDataStore implements MultiViewletDataStore
{
/**
*Hold the individual ViewletDataStores on a per type basis
*/
private Map wrappedStoreMap;
/**
* lists the fixities of the viewable.
* */
private List fixity;
/**
* elements is a map, going from indices represented as lists to
* ViewletData
* */
private Map elements;
/**
* Construct a SparseViewletStore given a list of integers (size), a
* fixity list (fixity).
* */
public SparseViewletStore(List size,
List fixity,
Viewable viewable) {
super(size, fixity, viewable, null);
this.fixity = fixity;
this.elements = new HashMap();
}
/**
* Traverses the entire structure recursively to collect together all the
* element indices.
*/
public ViewletRange getEntireViewletRange()
{
//return super.getEntireViewletRange();
return new ViewletRangeCollection(elements.keySet());
}
/**
* Shrinks the ViewletArray to size newSize. Assumes the top-level fixity is
* flexible.
*/
public void shrinkTo(List newSize) {
super.shrinkTo(newSize);
// Indicate to the table that rows/columns have been removed
fireTableStructureChanged();
}
/**
* Expand dimension nested at level dimension
by one.
*/
public void startExpandDimension(int dimension) {
super.startExpandDimension(dimension);
}
/**
* Implements the abstract getViewletDataAt method
*/
public ViewletData getViewletDataAt(List index) {
if(index.size() != getSize().size()) {
throw(new IllegalArgumentException());
}
return((ViewletData) getElement(index));
}
/**
* Implements the abstract setViewletDataAt method
*/
public void setViewletDataAt(List index, ViewletData data) {
if(index.size() != getSize().size()) {
throw(new IllegalArgumentException());
}
if (DebuggingSupport.logMessages) {
DebuggingSupport.logMessage(this, "SparseViewletStore setViewletDataAt index="+index+" data="+data);
}
if (data != null) {
setElement(index, data);
} else {
removeElement(index);
}
}
/**
* Get element with location index within the ViewletArray. Result may be a
* ViewletArray or a Viewlet, depending on the length of the index parameter.
*/
private Object getElement(List index)
{
Object result = elements.get(index);
return result;
}
/**
* Sets the element with location index within the ViewletArray. */
private void setElement(List index, Object data)
{
elements.put(index, data);
}
/**
* Removes the element with location index within the ViewletArray. */
private void removeElement(List index)
{
elements.remove(index);
}
/**
* Factory method for creating ViewletRange object from any given
* collection.
*
*
This defualt implementation will create a generic * ViewletRange. Subclasses can override this if specialised * structures make more sense. */ public ViewletRange createRange(Collection indices) { ViewletRange range = new ViewletRangeCollection(); // filter the range to only include those indices in the current // map for(Iterator it = indices.iterator(); it.hasNext(); ) { Object index = it.next(); if (elements.get(index)!=null) { range.add(index); } } return range; } /** * Factory method for creating ViewletRange objects to cover all * elements between the given start and end indices. * *
This defualt implementation will create a generic * ViewletRange. Subclasses can override this if specialised * structures make more sense. */ public ViewletRange createRange(List fromIndex, List toIndex) { ViewletRange indices = super.createRange(fromIndex, toIndex); ViewletRange range = new ViewletRangeCollection(); // filter the range to only include those indices in the current // map for(Iterator it = indices.iterator(); it.hasNext(); ) { Object index = it.next(); if (elements.get(index)!=null) { range.add(index); } } return range; } /** * Returns a wrapper store which intercedes whenever viewlet data * is get or set. * * Implements method from the MultiViewletDataStore interface * */ public ViewletDataStore getViewletDataStore(ViewletType type) { // Note the outer test is not synchronized to speed up normal code flow // but the test is duplicated within if (wrappedStoreMap == null) { synchronized(this) { if (wrappedStoreMap == null) { wrappedStoreMap=new HashMap(); } } } ViewletDataStore result = (ViewletDataStore)wrappedStoreMap.get(type); if (result == null) { synchronized(this) { if (result == null) { result = new WrappedMultiViewletDataStore(this, type); result.setSymRef(new SymRef(result,this.getSymRef(),type.getClass().getName())); wrappedStoreMap.put(type, result); } } } return result; } }