diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBPropertiesTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBPropertiesTests.java new file mode 100644 index 00000000000..e63210c51a2 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/pdom/tests/DBPropertiesTests.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2007 Symbian Software Systems 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: + * Andrew Ferguson (Symbian) - Initial implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.pdom.tests; + +import java.io.File; +import java.util.Iterator; +import java.util.Properties; + +import junit.framework.Test; + +import org.eclipse.cdt.core.testplugin.util.BaseTestCase; +import org.eclipse.cdt.internal.core.pdom.db.DBProperties; +import org.eclipse.cdt.internal.core.pdom.db.Database; +import org.eclipse.core.runtime.CoreException; + +/** + * Sanity check the DBProperties class + */ +public class DBPropertiesTests extends BaseTestCase { + File dbLoc; + Database db; + + public static Test suite() { + return suite(DBPropertiesTests.class); + } + + protected void setUp() throws Exception { + dbLoc = File.createTempFile("test", "db"); + dbLoc.deleteOnExit(); + db = new Database(dbLoc); + } + + protected void tearDown() throws Exception { + db.close(); + } + + public void testBasic() throws CoreException { + DBProperties properties = new DBProperties(db); + Properties expected = System.getProperties(); + for(Iterator i = expected.keySet().iterator(); i.hasNext(); ) { + String key = (String) i.next(); + String value = expected.getProperty(key); + if(value!=null) { + properties.setProperty(key, value); + } + } + for(Iterator i = expected.keySet().iterator(); i.hasNext(); ) { + String key = (String) i.next(); + String aValue = properties.getProperty(key); + assertEquals(expected.getProperty(key), aValue); + } + for(Iterator i = expected.keySet().iterator(); i.hasNext(); ) { + String key = (String) i.next(); + properties.removeProperty(key); + } + assertEquals(0, properties.getKeySet().size()); + + properties.delete(); + } + + + public void testLong() throws Exception { + DBProperties ps = new DBProperties(db); + + StringBuffer largeValue = new StringBuffer(); + for(int i=0; iString mapping. It is neither + * a Map or a Properties subclass, because of their more general applications. + */ +public class DBProperties { + static final int PROP_INDEX = 0; + static final int RECORD_SIZE = 4; + + protected BTree index; + protected Database db; + protected int record; + + /** + * Allocate storage for a new DBProperties record in the specified database + * @param db + * @throws CoreException + */ + public DBProperties(Database db) throws CoreException { + this.record= db.malloc(4); + this.index= new BTree(db, record + PROP_INDEX, DBProperty.getComparator(db)); + this.db= db; + } + + /** + * Creates an object for accessing an existing DBProperties record at the specified location of the specified database + * @param db + * @param record + * @throws CoreException + */ + public DBProperties(Database db, int record) throws CoreException { + this.record= record; + this.index= new BTree(db, record + PROP_INDEX, DBProperty.getComparator(db)); + this.db= db; + } + + /** + * Read the named property from this properties storage + * @param key a case-sensitive identifier for a property, or null + * @return the value associated with the key, or null if either no such property is set, or the specified key was null + * @throws CoreException + */ + public String getProperty(String key) throws CoreException { + if(key!=null) { + DBProperty existing= DBProperty.search(db, index, key); + if(existing!=null) { + return existing.getValue().getString(); + } + } + return null; + } + + /** + * Read the named property from this properties storage, returning the default value if there is no such property + * @param key a case-sensitive identifier for a property, or null + * @param defaultValue a value to return in case the specified key was null + * @return the value associated with the key, or the specified default value if either no such property is set, or + * the specified key was null + * @throws CoreException + */ + public String getProperty(String key, String defaultValue) throws CoreException { + String val= getProperty(key); + return (val == null) ? defaultValue : val; + } + + /** + * Returns a Set of property names (Strings) stored in this object + * @return a Set of property names (Strings) stored in this object + * @throws CoreException + */ + public Set getKeySet() throws CoreException { + return DBProperty.getKeySet(db, index); + } + + /** + * Write the key, value mapping to the properties. If a mapping for the + * same key already exists, it is overwritten. + * @param key a non-null property name + * @param value a value to associate with the key. may not be null. + * @throws CoreException + * @throws NullPointerException if key is null + */ + public void setProperty(String key, String value) throws CoreException { + removeProperty(key); + DBProperty newProperty= new DBProperty(db, key, value); + index.insert(newProperty.getRecord()); + } + + /** + * Deletes a property from this DBProperties object + * @param key + * @return whether a property with matching key existed and was removed, or false if the key was null + * @throws CoreException + */ + public boolean removeProperty(String key) throws CoreException { + if(key!=null) { + DBProperty existing= DBProperty.search(db, index, key); + if(existing != null) { + index.delete(existing.getRecord()); + existing.delete(); + return true; + } + } + return false; + } + + /** + * Deletes all properties, does not delete the record associated with the object itself - that is + * it can be repopulated. + * @throws CoreException + */ + private void clear() throws CoreException { + index.accept(new IBTreeVisitor(){ + public int compare(int record) throws CoreException { + return 0; + } + public boolean visit(int record) throws CoreException { + new DBProperty(db, record).delete(); + return false; // there should never be duplicates + } + }); + } + + /** + * Deletes all properties stored in this object and the record associated with this object itself. + *

+ * The behaviour of objects of this class after calling this method is undefined + * @throws CoreException + */ + public void delete() throws CoreException { + clear(); + db.free(record); + } + + private static class DBProperty { + static final int KEY = 0; + static final int VALUE = 4; + static final int RECORD_SIZE = 8; + + Database db; + int record; + + public int getRecord() { + return record; + } + + /** + * Allocates and initializes a record in the specified database for a DBProperty record + * @param db + * @param key a non-null property name + * @param value a non-null property value + * @throws CoreException + */ + DBProperty(Database db, String key, String value) throws CoreException { + assert key!=null; + assert value!=null; + IString dbkey= db.newString(key); + IString dbvalue= db.newString(value); + this.record= db.malloc(RECORD_SIZE); + db.putInt(record + KEY, dbkey.getRecord()); + db.putInt(record + VALUE, dbvalue.getRecord()); + this.db= db; + } + + /** + * Returns an object for accessing an existing DBProperty record at the specified location in the + * specified database + * @param db + * @param record + */ + DBProperty(Database db, int record) { + this.record= record; + this.db= db; + } + + public IString getKey() throws CoreException { + return db.getString(db.getInt(record + KEY)); + } + + public IString getValue() throws CoreException { + return db.getString(db.getInt(record + VALUE)); + } + + public static IBTreeComparator getComparator(final Database db) { + return new IBTreeComparator() { + public int compare(int record1, int record2) throws CoreException { + IString left= db.getString(db.getInt(record1 + KEY)); + IString right= db.getString(db.getInt(record2 + KEY)); + return left.compare(right, true); + } + }; + } + + public static DBProperty search(final Database db, final BTree index, final String key) throws CoreException { + final DBProperty[] result= new DBProperty[1]; + index.accept(new IBTreeVisitor(){ + public int compare(int record) throws CoreException { + return db.getString(db.getInt(record + KEY)).compare(key, true); + } + public boolean visit(int record) throws CoreException { + result[0] = new DBProperty(db, record); + return false; // there should never be duplicates + } + }); + return result[0]; + } + + public static Set getKeySet(final Database db, final BTree index) throws CoreException { + final Set result= new HashSet(); + index.accept(new IBTreeVisitor(){ + public int compare(int record) throws CoreException { + return 0; + } + public boolean visit(int record) throws CoreException { + result.add(new DBProperty(db, record).getKey().getString()); + return true; // there should never be duplicates + } + }); + return result; + } + + public void delete() throws CoreException { + db.getString(db.getInt(record + KEY)).delete(); + db.getString(db.getInt(record + VALUE)).delete(); + db.free(record); + } + } +}