001: /**
002: * Copyright (C) 2001-2005 France Telecom R&D
003: */package org.objectweb.speedo.generation.mivisitor.jdo;
004:
005: import java.util.HashMap;
006:
007: import org.objectweb.speedo.api.SpeedoException;
008: import org.objectweb.speedo.api.SpeedoProperties;
009: import org.objectweb.speedo.generation.mivisitor.AbstractMetaInfoVisitor;
010: import org.objectweb.speedo.lib.Personality;
011: import org.objectweb.speedo.metadata.SpeedoClass;
012: import org.objectweb.speedo.metadata.SpeedoCollection;
013: import org.objectweb.speedo.metadata.SpeedoColumn;
014: import org.objectweb.speedo.metadata.SpeedoDiscriminator;
015: import org.objectweb.speedo.metadata.SpeedoExtension;
016: import org.objectweb.speedo.metadata.SpeedoField;
017: import org.objectweb.speedo.metadata.SpeedoInheritance;
018: import org.objectweb.speedo.metadata.SpeedoMap;
019: import org.objectweb.speedo.metadata.SpeedoTable;
020: import org.objectweb.util.monolog.api.BasicLevel;
021:
022: /**
023: * Translates JDO extension dedicated for the mapping into normal meta
024: * information (non extension meta object).
025: *
026: * @author S.Chassande-Barrioz
027: */
028: public class MappingExtension2Jdo extends AbstractMetaInfoVisitor
029: implements SpeedoProperties {
030:
031: public MappingExtension2Jdo(Personality p) {
032: super (p);
033: }
034:
035: private void deprecate(String ext, String msg) {
036: logger.log(BasicLevel.INFO, "Extension '" + ext
037: + " is deprecated: " + msg);
038: }
039:
040: public void visitExtension(SpeedoExtension se)
041: throws SpeedoException {
042: logger.log(BasicLevel.DEBUG, "Extension '" + se.key + "="
043: + se.value);
044: if (se.owner instanceof SpeedoClass) {
045: SpeedoClass sc = (SpeedoClass) se.owner;
046: //Main table name
047: if (SQL_NAME.equals(se.key)) {
048: sc.mainTable = new SpeedoTable();
049: sc.mainTable.name = se.value;
050: sc.mainTable.catalog = null;
051: sc.mainTable.schema = null;
052: } else if (INHERITANCE_FILTER.equals(se.key)) {
053: setDiscriminatorElement(sc, se.value);
054: } else if (INHERITANCE_KEY.equals(se.key)) {
055: if (sc.inheritance == null) {
056: sc.inheritance = new SpeedoInheritance(sc);
057: }
058: if (sc.inheritance.discriminatorValues == null) {
059: sc.inheritance.discriminatorValues = new HashMap();
060: }
061: SpeedoDiscriminator sd = sc.inheritance.discriminator;
062: if (sd == null || !sd.hasDiscriminator()) {
063: //find the discriminator
064: SpeedoClass current = sc;
065: while (current != null && sd == null) {
066: if (current.inheritance != null
067: && current.inheritance.discriminator != null
068: && current.inheritance.discriminator
069: .hasDiscriminator()) {
070: sd = current.inheritance.discriminator;
071: } else {
072: String f = current
073: .getExtensionValueByKey(INHERITANCE_FILTER);
074: if (f != null) {
075: sd = setDiscriminatorElement(current, f);
076: }
077: }
078: if (sd == null) {
079: current = current.getSuper();
080: }
081: }
082: if (sd == null || !sd.hasDiscriminator()) {
083: throw new SpeedoException(
084: "Extension '"
085: + INHERITANCE_KEY
086: + "' specified without filter definition in the "
087: + sc.getSourceDesc());
088: }
089: }
090: if (sd.expression == null) {
091: sc.inheritance.discriminatorValues.put(sd.elements
092: .get(0), se.value);
093: } else {
094: sc.inheritance.discriminatorValues.put(
095: sd.expression, se.value);
096: }
097: }
098:
099: } else if (se.owner instanceof SpeedoField) {
100: SpeedoField sf = (SpeedoField) se.owner;
101: if (SQL_NAME.equals(se.key)) {
102: if (sf.getReferencedClass() == null) {
103: initColumnField(sf);
104: try {
105: sf.columns[0].name = se.value;
106: } catch (RuntimeException e) {
107: logger.log(BasicLevel.WARN, sf.getSourceDesc()
108: + ", cols=" + sf.columns[0], e);
109: logger.log(BasicLevel.WARN, "se.value"
110: + se.value);
111: throw e;
112: }
113: deprecate(SQL_NAME,
114: "use the 'column' attribut of the tag 'field'.");
115: } else {
116: logger.log(BasicLevel.WARN,
117: "Extension 'sql-name' cannot be specified for a non primitive field: "
118: + sf.getSourceDesc());
119: }
120:
121: } else if (SQL_TYPE.equals(se.key)) {
122: if (sf.getReferencedClass() == null) {
123: initColumnField(sf);
124: sf.columns[0].sqlType = se.value;
125: deprecate(SQL_TYPE,
126: "use the 'sql-type' attribut of the tag 'field'.");
127: } else {
128: logger.log(BasicLevel.WARN,
129: "Extension 'sql-type' cannot be specified for a non primitive field: "
130: + sf.getSourceDesc());
131: }
132:
133: } else if (SIZE.equals(se.key)) {
134: if (sf.getReferencedClass() == null) {
135: initColumnField(sf);
136: sf.columns[0].length = Integer.parseInt(se.value);
137: deprecate(SIZE,
138: "use the 'size' attribut of the tag 'field'.");
139: } else {
140: logger.log(BasicLevel.WARN,
141: "Extension 'size' cannot be specified for a non primitive field: "
142: + sf.getSourceDesc());
143: }
144:
145: } else if (SCALE.equals(se.key)) {
146: if (sf.getReferencedClass() == null) {
147: initColumnField(sf);
148: sf.columns[0].scale = Integer.parseInt(se.value);
149: deprecate(SCALE,
150: "use the 'scale' attribut of the tag 'field'.");
151: } else {
152: logger.log(BasicLevel.WARN,
153: "Extension 'scale' cannot be specified for a non primitive field: "
154: + sf.getSourceDesc());
155: }
156:
157: } else if (REVERSE_FIELD.equals(se.key)) {
158: //@see org.objectweb.speedo.generation.mivisitor.ReverseFieldAdder
159: } else if (ELEMENT.equals(se.key)) {
160: if (sf.jdoTuple != null
161: && sf.getReferencedClass() == null) {
162: initColumnField(sf);
163: sf.columns[0].name = se.value;
164: deprecate(ELEMENT,
165: "use the 'column' attribut of the tag 'field'.");
166: } else {
167: logger
168: .log(
169: BasicLevel.WARN,
170: "Extension 'element-sql-name' cannot be specified for a field which is not a collection of primitive element: "
171: + sf.getSourceDesc());
172: }
173:
174: } else if (ELEMENT_TYPE.equals(se.key)) {
175: if (sf.jdoTuple != null
176: && sf.getReferencedClass() == null) {
177: initColumnField(sf);
178: sf.columns[0].sqlType = se.value;
179: deprecate(ELEMENT_TYPE,
180: "use the 'column' attribut of the tag 'field'.");
181: } else {
182: logger
183: .log(
184: BasicLevel.WARN,
185: "Extension 'element-sql-type' cannot be specified for a field which is not a collection of primitive element: "
186: + sf.getSourceDesc());
187: }
188: } else if (INDEX.equals(se.key)) {
189: if (sf.jdoTuple instanceof SpeedoCollection) {
190: initCollectionIndexColumn((SpeedoCollection) sf.jdoTuple).name = se.value;
191: } else if (sf.jdoTuple instanceof SpeedoMap) {
192: initMapKeyColumn((SpeedoMap) sf.jdoTuple).name = se.value;
193: } else {
194: logger
195: .log(
196: BasicLevel.WARN,
197: "Extension 'index-sql-name' cannot be specified for a field which is not a collection or a map: "
198: + sf.getSourceDesc());
199: }
200: } else if (INDEX_TYPE.equals(se.key)) {
201: if (sf.jdoTuple instanceof SpeedoCollection) {
202: initCollectionIndexColumn((SpeedoCollection) sf.jdoTuple).sqlType = se.value;
203: } else if (sf.jdoTuple instanceof SpeedoMap) {
204: initMapKeyColumn((SpeedoMap) sf.jdoTuple).sqlType = se.value;
205: } else {
206: logger
207: .log(
208: BasicLevel.WARN,
209: "Extension 'index-sql-type' cannot be specified for a field which is not a collection or a map: "
210: + sf.getSourceDesc());
211: }
212: }
213:
214: }
215: super .visitExtension(se);
216: }
217:
218: //public
219: /**
220: * If no column is specified for the field, a new one is created. By
221: * default a field is map over a single column.
222: *
223: * @param sf is the SpeedoField which the column must be initialized if not
224: * already done.
225: */
226: private void initColumnField(SpeedoField sf) {
227: if (sf.columns == null || sf.columns.length == 0) {
228: //
229: sf.columns = new SpeedoColumn[] { new SpeedoColumn() };
230: if (sf.moClass.mainTable != null) {
231: sf.columns[0].table = sf.moClass.mainTable;
232: }
233: }
234: }
235:
236: private SpeedoColumn initCollectionIndexColumn(SpeedoCollection sc) {
237: if (sc.indexColumns == null) {
238: sc.indexColumns = new SpeedoColumn();
239: if (sc.moField.join != null
240: && sc.moField.join.extTable != null) {
241: sc.indexColumns.table = sc.moField.join.extTable;
242: }
243: }
244: return sc.indexColumns;
245: }
246:
247: private SpeedoColumn initMapKeyColumn(SpeedoMap sm) {
248: if (sm.keyColumns == null) {
249: sm.keyColumns = new SpeedoColumn();
250: if (sm.moField.join != null
251: && sm.moField.join.extTable != null) {
252: sm.keyColumns.table = sm.moField.join.extTable;
253: }
254: }
255: return sm.keyColumns;
256: }
257:
258: private SpeedoDiscriminator setDiscriminatorElement(SpeedoClass sc,
259: String value) {
260: if (sc.inheritance == null) {
261: sc.inheritance = new SpeedoInheritance();
262: }
263: if (sc.inheritance.discriminator == null) {
264: sc.inheritance.discriminator = new SpeedoDiscriminator();
265: }
266: SpeedoDiscriminator sd = sc.inheritance.discriminator;
267: sd.strategy = SpeedoDiscriminator.STRATEGY_MAP_VALUE;
268: SpeedoField sf = sc.getField(value);
269: if (sf == null) {
270: sd.expression = value;
271: } else if (!sd.elements.contains(sf)) {
272: sd.elements.add(sf);
273: }
274: return sd;
275: }
276: }
|