001: /**********************************************************************
002: Copyright (c) 2004 Erik Bengtson and others. All rights reserved.
003: Licensed under the Apache License, Version 2.0 (the "License");
004: you may not use this file except in compliance with the License.
005: You may obtain a copy of the License at
006:
007: http://www.apache.org/licenses/LICENSE-2.0
008:
009: Unless required by applicable law or agreed to in writing, software
010: distributed under the License is distributed on an "AS IS" BASIS,
011: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: See the License for the specific language governing permissions and
013: limitations under the License.
014:
015: Contributors:
016: 2004 Andy Jefferson - added javadocs.
017: 2004 Andy Jefferson - added unique, indexed
018: 2005 Andy Jefferson - changed foreignKey attr to delete-action
019: ...
020: **********************************************************************/package org.jpox.metadata;
021:
022: import java.util.ArrayList;
023: import java.util.List;
024:
025: import org.jpox.ClassLoaderResolver;
026: import org.jpox.util.StringUtils;
027:
028: /**
029: * This element specifies the mapping for the element component of arrays and
030: * collections.
031: *
032: * If only one column is mapped, and no additional information is needed for the
033: * column, then the column attribute can be used. Otherwise, the column
034: * element(s) are used.
035: *
036: * The serialized attribute specifies that the key values are to be serialized
037: * into the named column.
038: *
039: * The foreign-key attribute specifies the name of a foreign key to be
040: * generated.
041: *
042: * @since 1.1
043: * @version $Revision: 1.24 $
044: */
045: public abstract class AbstractElementMetaData extends MetaData
046: implements ColumnMetaDataContainer {
047: /**
048: * Columns ColumnMetaData
049: */
050: protected final List columns = new ArrayList();
051:
052: /**
053: * IndexMetaData
054: */
055: protected IndexMetaData indexMetaData;
056:
057: /**
058: * The indexing value
059: */
060: protected IndexedValue indexed = null;
061:
062: /**
063: * UniqueMetaData.
064: */
065: protected UniqueMetaData uniqueMetaData;
066:
067: /**
068: * Whether to add a unique constraint
069: */
070: protected final boolean uniqueConstraint;
071:
072: /**
073: * ForeignKeyMetaData
074: */
075: protected ForeignKeyMetaData foreignKeyMetaData;
076:
077: /**
078: * EmbeddedMetaData
079: */
080: protected EmbeddedMetaData embeddedMetaData;
081:
082: /** column name value. */
083: protected String columnName;
084:
085: /** Field that this is mapped to. */
086: protected String mappedBy;
087:
088: // -------------------------------------------------------------------------
089: // Fields below here are not represented in the output MetaData. They are
090: // for use internally in the operation of the JDO system. The majority are
091: // for convenience to save iterating through the fields since the fields
092: // are fixed once initialised.
093:
094: protected ColumnMetaData columnMetaData[];
095:
096: /**
097: * Constructor to create a copy of the passed metadata object applying the passed parent.
098: * @param parent The parent
099: * @param aemd The metadata to copy
100: */
101: public AbstractElementMetaData(MetaData parent,
102: AbstractElementMetaData aemd) {
103: super (parent);
104: this .columnName = aemd.columnName;
105: this .uniqueConstraint = aemd.uniqueConstraint;
106: this .indexed = aemd.indexed;
107: this .mappedBy = aemd.mappedBy;
108: // TODO These should be changed to be copies
109: this .indexMetaData = aemd.indexMetaData;
110: this .uniqueMetaData = aemd.uniqueMetaData;
111: this .foreignKeyMetaData = aemd.foreignKeyMetaData;
112: this .embeddedMetaData = aemd.embeddedMetaData;
113: for (int i = 0; i < columns.size(); i++) {
114: addColumn(new ColumnMetaData(this ,
115: (ColumnMetaData) aemd.columns.get(i)));
116: }
117: }
118:
119: /**
120: * Constructor.
121: * @param parent Parent element
122: * @param columnName Name of column
123: * @param deleteAction attribute delete-action value
124: * @param updateAction attribute update-action value
125: * @param indexed The indexing value
126: * @param unique Whether to add a unique constraint
127: * @param mappedBy Mapped-by field for this element/key/value
128: */
129: public AbstractElementMetaData(MetaData parent, String columnName,
130: String deleteAction, String updateAction, String indexed,
131: String unique, String mappedBy) {
132: super (parent);
133:
134: this .columnName = (StringUtils.isWhitespace(columnName) ? null
135: : columnName);
136:
137: if (deleteAction != null || updateAction != null) {
138: foreignKeyMetaData = new ForeignKeyMetaData(null, null,
139: null, null, deleteAction, updateAction);
140: }
141:
142: this .indexed = IndexedValue.getIndexedValue(indexed);
143:
144: if (unique != null && unique.equalsIgnoreCase("true")) {
145: uniqueConstraint = true;
146: } else {
147: uniqueConstraint = false;
148: }
149: this .mappedBy = (StringUtils.isWhitespace(mappedBy) ? null
150: : mappedBy);
151: }
152:
153: /**
154: * Populate the metadata
155: * @param clr the ClassLoaderResolver
156: * @param primary the primary ClassLoader to use (or null)
157: */
158: public void populate(ClassLoaderResolver clr, ClassLoader primary) {
159: if (embeddedMetaData != null) {
160: embeddedMetaData.populate(clr, primary);
161: }
162: }
163:
164: /**
165: * Method to initialise the object, creating any convenience arrays needed.
166: * Initialises all sub-objects.
167: */
168: public void initialise() {
169: // Cater for user specifying column name, or columns
170: if (columns.size() == 0 && columnName != null) {
171: columnMetaData = new ColumnMetaData[1];
172: columnMetaData[0] = new ColumnMetaData(this , columnName);
173: columnMetaData[0].initialise();
174: } else {
175: columnMetaData = new ColumnMetaData[columns.size()];
176: for (int i = 0; i < columnMetaData.length; i++) {
177: columnMetaData[i] = (ColumnMetaData) columns.get(i);
178: columnMetaData[i].initialise();
179: }
180: }
181:
182: // Interpret the "indexed" value to create our IndexMetaData where it wasn't specified that way
183: if (indexMetaData == null && columnMetaData != null
184: && indexed != null && indexed != IndexedValue.FALSE) {
185: indexMetaData = new IndexMetaData(null, null,
186: (indexed == IndexedValue.UNIQUE) ? "true" : "false");
187: for (int i = 0; i < columnMetaData.length; i++) {
188: indexMetaData.addColumn(columnMetaData[i]);
189: }
190: }
191: if (indexMetaData != null) {
192: indexMetaData.initialise();
193: }
194:
195: if (uniqueMetaData == null && uniqueConstraint) {
196: uniqueMetaData = new UniqueMetaData(null, columnName, null);
197: for (int i = 0; i < columnMetaData.length; i++) {
198: uniqueMetaData.addColumn(columnMetaData[i]);
199: }
200: }
201: if (uniqueMetaData != null) {
202: uniqueMetaData.initialise();
203: }
204:
205: if (foreignKeyMetaData != null) {
206: foreignKeyMetaData.initialise();
207: }
208:
209: if (embeddedMetaData != null) {
210: embeddedMetaData.initialise();
211: }
212:
213: setInitialised();
214: }
215:
216: // -------------------------------- Accessors ------------------------------
217:
218: /**
219: * Accessor for column name.
220: * @return Returns the column name.
221: */
222: public final String getColumnName() {
223: return columnName;
224: }
225:
226: /**
227: * Accessor for the field in the value that stores the key
228: * @return Field in the value that stores the key
229: */
230: public String getMappedBy() {
231: return mappedBy;
232: }
233:
234: /**
235: * Accessor for columnMetaData
236: * @return Returns the columnMetaData.
237: */
238: public final ColumnMetaData[] getColumnMetaData() {
239: return columnMetaData;
240: }
241:
242: /**
243: * Accessor for embeddedMetaData
244: * @return Returns the embeddedMetaData.
245: */
246: public final EmbeddedMetaData getEmbeddedMetaData() {
247: return embeddedMetaData;
248: }
249:
250: /**
251: * Accessor for foreignKeyMetaData
252: * @return Returns the foreignKeyMetaData.
253: */
254: public final ForeignKeyMetaData getForeignKeyMetaData() {
255: return foreignKeyMetaData;
256: }
257:
258: /**
259: * Accessor for indexMetaData
260: * @return Returns the indexMetaData.
261: */
262: public final IndexMetaData getIndexMetaData() {
263: return indexMetaData;
264: }
265:
266: /**
267: * Accessor for uniqueMetaData
268: * @return Returns the uniqueMetaData.
269: */
270: public final UniqueMetaData getUniqueMetaData() {
271: return uniqueMetaData;
272: }
273:
274: // ------------------------------ Mutators ---------------------------------
275:
276: /**
277: * Add a new ColumnMetaData element
278: * @param colmd The Column MetaData
279: */
280: public void addColumn(ColumnMetaData colmd) {
281: columns.add(colmd);
282: colmd.parent = this ;
283: }
284:
285: /**
286: * Mutator for the Embedded MetaData
287: * @param embeddedMetaData The embeddedMetaData to set.
288: */
289: public final void setEmbeddedMetaData(
290: EmbeddedMetaData embeddedMetaData) {
291: this .embeddedMetaData = embeddedMetaData;
292: }
293:
294: /**
295: * Mutator for the Foreign Key MetaData
296: * @param foreignKeyMetaData The foreignKeyMetaData to set.
297: */
298: public final void setForeignKeyMetaData(
299: ForeignKeyMetaData foreignKeyMetaData) {
300: this .foreignKeyMetaData = foreignKeyMetaData;
301: }
302:
303: /**
304: * Mutator for the Index MetaData
305: * @param indexMetaData The indexMetaData to set.
306: */
307: public final void setIndexMetaData(IndexMetaData indexMetaData) {
308: this .indexMetaData = indexMetaData;
309: }
310:
311: /**
312: * Mutator for the Unique MetaData
313: * @param uniqueMetaData The uniqueMetaData to set.
314: */
315: public final void setUniqueMetaData(UniqueMetaData uniqueMetaData) {
316: this.uniqueMetaData = uniqueMetaData;
317: }
318: }
|