001: /**
002: * Copyright (C) 2007 NetMind Consulting Bt.
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 3 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package hu.netmind.persistence;
018:
019: import java.util.*;
020: import hu.netmind.persistence.parser.*;
021:
022: /**
023: * Collection handler implementation.
024: * @author Brautigam Robert
025: * @version Revision: $Revision$
026: */
027: public class CollectionHandler extends ContainerHandler {
028: private Class collectionClass;
029:
030: /**
031: * Constructor.
032: */
033: public CollectionHandler(StoreContext context, Class collectionClass) {
034: super (context);
035: this .collectionClass = collectionClass;
036: }
037:
038: public Class getContainerClass() {
039: return collectionClass;
040: }
041:
042: /**
043: * Create the subtable for the collection.
044: */
045: public void ensureTableExists(ClassInfo parentInfo,
046: String attributeName, boolean create) {
047: Transaction tx = context.getTransactionTracker()
048: .getTransaction(TransactionTracker.TX_REQUIRED);
049: tx.begin();
050: try {
051: // Ensure map helper table
052: HashMap listAttributeTypes = new HashMap();
053: listAttributeTypes.put("persistence_id", Long.class);
054: listAttributeTypes.put("persistence_start", Long.class);
055: listAttributeTypes.put("persistence_end", Long.class);
056: listAttributeTypes.put("persistence_txstartid", Long.class);
057: listAttributeTypes.put("persistence_txstart", Long.class);
058: listAttributeTypes.put("persistence_txendid", Long.class);
059: listAttributeTypes.put("persistence_txend", Long.class);
060: listAttributeTypes.put("value", Long.class);
061: Vector listKeys = new Vector();
062: listKeys.add("persistence_id");
063: listKeys.add("persistence_txstart");
064: listKeys.add("value");
065: context.getDatabase().ensureTable(tx,
066: parentInfo.getSubTableName(attributeName),
067: listAttributeTypes, listKeys, create);
068: } catch (StoreException e) {
069: tx.markRollbackOnly();
070: throw e;
071: } catch (Throwable e) {
072: tx.markRollbackOnly();
073: throw new StoreException("Unknown exception", e);
074: } finally {
075: tx.commit();
076: }
077: }
078:
079: /**
080: * Create the approriate symbol entry when parsing a query.
081: */
082: public WhereResolver.SymbolTableEntry getSymbolEntry(
083: AttributeSpecifier spec,
084: WhereResolver.SymbolTableEntry previousEntry,
085: ClassInfo previousInfo, ReferenceTerm previousTerm) {
086: String attributeName = spec.getIdentifier();
087: // Create entry
088: WhereResolver.SymbolTableEntry entry = new WhereResolver.SymbolTableEntry();
089: entry.alias = null;
090: entry.tableName = previousInfo.getSubTableName(attributeName);
091: entry.automatic = true;
092: entry.referenceColumn = "value";
093: entry.type = WhereResolver.SymbolTableEntry.TYPE_HANDLED;
094: // Create expression
095: Expression connectorExpression = new Expression();
096: ReferenceTerm leftTerm1 = previousTerm;
097: if (previousEntry.automatic)
098: previousEntry.termList.add(leftTerm1);
099: connectorExpression.add(leftTerm1);
100: connectorExpression.add("=");
101: ReferenceTerm rightTerm1 = new ReferenceTerm(entry.tableName,
102: entry.alias, "persistence_id");
103: entry.termList.add(rightTerm1);
104: connectorExpression.add(rightTerm1);
105: entry.expression = connectorExpression;
106: // Return
107: return entry;
108: }
109:
110: /**
111: * Determine the next class info after the given specifier.
112: */
113: public ClassInfo getSymbolInfo(
114: WhereResolver.SymbolTableEntry entry,
115: AttributeSpecifier spec) throws ParserException {
116: // A list should be the last item, so there should be
117: // no next specifier.
118: throw new ParserException(ParserException.ABORT,
119: "list type found, and is not the last item, but it should");
120: }
121: }
|