| /******************************************************************************* |
| * 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.rephraserengine.internal.db.org.eclipse.cdt.internal.core.pdom.db; |
| |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.CoreException; |
| |
| /** |
| * DBProperties is a bare-bones implementation of a String->String 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(RECORD_SIZE); |
| 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 |
| */ |
| public 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. |
| * <br><br> |
| * <b>The behaviour of objects of this class after calling this method is undefined</b> |
| * @throws CoreException |
| */ |
| public void delete() throws CoreException { |
| clear(); |
| db.free(record); |
| } |
| |
| public int getRecord() { |
| return 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); |
| } |
| } |
| } |