001: /*
002: * Copyright 2004 (C) TJDO.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the TJDO License version 1.0.
006: * See the terms of the TJDO License in the documentation provided with this software.
007: *
008: * $Id: RequestUsingFields.java,v 1.2 2004/02/01 18:22:42 jackknifebarber Exp $
009: */
010:
011: package com.triactive.jdo.store;
012:
013: import com.triactive.jdo.model.ClassMetaData;
014: import com.triactive.jdo.util.IntArrayList;
015: import javax.jdo.JDOFatalInternalException;
016:
017: /**
018: * A storage request involving specific fields of a persistence-capable
019: * class.
020: *
021: * @author <a href="mailto:mmartin5@austin.rr.com">Mike Martin</a>
022: * @version $Revision: 1.2 $
023: */
024:
025: abstract class RequestUsingFields extends Request {
026: /**
027: * The fields involved in this request that use ColumnMappings.
028: * Null if there are no such fields.
029: */
030: protected final int[] colFields;
031:
032: /**
033: * The fields involved in this request that use ComplexMappings.
034: * Null if there are no such fields.
035: */
036: protected final int[] cpxFields;
037:
038: /**
039: * The ColumnMappings used by fields involved in this request, indexed by
040: * absolute field number.
041: * Null if {@link #colFields} is null.
042: */
043: protected final ColumnMapping[] colFieldMappings;
044:
045: /**
046: * The ComplexMappings used by fields involved in this request, indexed by
047: * absolute field number.
048: * Null if {@link #cpxFields} is null.
049: */
050: protected final ComplexMapping[] cpxFieldMappings;
051:
052: /**
053: * Constructs a request involving all fields of the class backed by the
054: * given table.
055: *
056: * @param table
057: * The table on which the request will operate.
058: */
059:
060: protected RequestUsingFields(final ClassBaseTable table) {
061: this (table, new FieldIterator() {
062: private ClassMetaData cmd = table.getClassMetaData();
063: private int fn = cmd.getInheritedFieldCount();
064: private int end = fn + cmd.getFieldCount();
065:
066: public int nextFieldNumber() {
067: return fn < end ? fn++ : -1;
068: }
069: });
070: }
071:
072: /**
073: * Constructs a request involving the specified fields of the class backed
074: * by the given table.
075: *
076: * @param table
077: * The table on which the request will operate.
078: * @param fieldNumbers
079: * The fields that will be involved in the request.
080: */
081:
082: protected RequestUsingFields(final ClassBaseTable table,
083: final int[] fieldNumbers) {
084: this (table, new FieldIterator() {
085: private ClassMetaData cmd = table.getClassMetaData();
086: private int start = cmd.getInheritedFieldCount();
087: private int end = start + cmd.getFieldCount();
088: private int idx = 0;
089:
090: public int nextFieldNumber() {
091: while (idx < fieldNumbers.length) {
092: int fn = fieldNumbers[idx++];
093:
094: if (fn >= start && fn < end)
095: return fn;
096: }
097:
098: return -1;
099: }
100: });
101: }
102:
103: /**
104: * Internal constructor that takes the field number list from a
105: * FieldIterator.
106: */
107:
108: private RequestUsingFields(ClassBaseTable table,
109: FieldIterator fieldIterator) {
110: super (table);
111:
112: ClassMetaData cmd = table.getClassMetaData();
113: int declaredFieldCount = cmd.getFieldCount();
114: int inheritedFieldCount = cmd.getInheritedFieldCount();
115: int totalFieldCount = inheritedFieldCount + declaredFieldCount;
116:
117: IntArrayList colfn = new IntArrayList(declaredFieldCount);
118: IntArrayList cpxfn = new IntArrayList(declaredFieldCount);
119: ColumnMapping[] colfm = new ColumnMapping[totalFieldCount];
120: ComplexMapping[] cpxfm = new ComplexMapping[totalFieldCount];
121:
122: int field;
123:
124: while ((field = fieldIterator.nextFieldNumber()) >= 0) {
125: if (table.isFieldPersistent(field)) {
126: Mapping m = table.getFieldMapping(field);
127:
128: if (m instanceof ColumnMapping) {
129: colfn.add(field);
130: colfm[field] = (ColumnMapping) m;
131: } else if (m instanceof ComplexMapping) {
132: cpxfn.add(field);
133: cpxfm[field] = (ComplexMapping) m;
134: } else
135: throw new JDOFatalInternalException(
136: "Unknown mapping: " + m);
137: }
138: }
139:
140: if (colfn.isEmpty()) {
141: colFields = null;
142: colFieldMappings = null;
143: } else {
144: colFields = colfn.toArray();
145: colFieldMappings = colfm;
146: }
147:
148: if (cpxfn.isEmpty()) {
149: cpxFields = null;
150: cpxFieldMappings = null;
151: } else {
152: cpxFields = cpxfn.toArray();
153: cpxFieldMappings = cpxfm;
154: }
155: }
156:
157: /**
158: * An object that iterates over a set of field numbers.
159: */
160: private interface FieldIterator {
161: /**
162: * Returns the next field number.
163: *
164: * @return The next field number, or -1 if there are no more fields.
165: */
166: int nextFieldNumber();
167: }
168: }
|