001: /**
002: * Copyright (C) 2001-2006 France Telecom R&D
003: */package org.objectweb.speedo.generation.mivisitor;
004:
005: import org.objectweb.asm.Type;
006: import org.objectweb.speedo.api.SpeedoException;
007: import org.objectweb.speedo.lib.Personality;
008: import org.objectweb.speedo.metadata.SpeedoClass;
009: import org.objectweb.speedo.metadata.SpeedoColumn;
010: import org.objectweb.speedo.metadata.SpeedoDiscriminator;
011: import org.objectweb.speedo.metadata.SpeedoElement;
012: import org.objectweb.speedo.metadata.SpeedoField;
013: import org.objectweb.speedo.metadata.SpeedoNoFieldColumn;
014:
015: import java.util.Collections;
016: import java.util.Iterator;
017: import java.util.Map;
018:
019: public class DiscriminatorVisitor extends AbstractMetaInfoVisitor {
020:
021: public DiscriminatorVisitor(Personality p) {
022: super (p);
023: }
024:
025: protected String getLoggerName() {
026: return super .getLoggerName() + ".discriminator";
027: }
028:
029: public void visitClass(SpeedoClass sc) throws SpeedoException {
030: getDiscriminatorFromParent(sc);
031: super .visitClass(sc);
032: }
033:
034: private SpeedoDiscriminator getDiscriminatorFromParent(
035: SpeedoClass sc) throws SpeedoException {
036: if (sc.inheritance == null) {
037: return null;
038: }
039: SpeedoDiscriminator sd = sc.inheritance.discriminator;
040: SpeedoClass parent = sc.getSuper();
041: if (parent == null) {
042: // sc is the root of the tree
043: if (sd != null) {
044: checkColumn(sc, sd);
045: if (sd.strategy == SpeedoDiscriminator.STRATEGY_CLASS_NAME) {
046: SpeedoElement se = (SpeedoElement) sd.elements
047: .get(0);
048: if (se instanceof SpeedoNoFieldColumn) {
049: ((SpeedoNoFieldColumn) se).type = Type
050: .getDescriptor(String.class);
051: }
052: }
053: }
054: } else {
055: sd = getDiscriminatorFromParent(parent);
056: // use the discriminator of parent
057: if (sd != null) {
058: SpeedoDiscriminator oldsd = sc.inheritance.discriminator;
059: if (oldsd != sd) {
060: sc.inheritance.discriminator = sd;
061: if (sc.inheritance.discriminatorValues != null) {
062: //Replace old keys in discriminator map values
063: replaceOldKeys(sd, oldsd,
064: sc.inheritance.discriminatorValues);
065: }
066: }
067: }
068: }
069: if (sd != null
070: && sd.strategy == SpeedoDiscriminator.STRATEGY_CLASS_NAME
071: && sc.inheritance.discriminatorValues == null) {
072: //Assign the value corresponding to the strategy
073: sc.inheritance.discriminatorValues = Collections
074: .singletonMap(sd.elements.get(0), sc.getFQName());
075: }
076: return sd;
077: }
078:
079: private void replaceOldKeys(SpeedoDiscriminator sd,
080: SpeedoDiscriminator oldsd, Map discValues) {
081: if (oldsd == null || sd == null) {
082: return;
083: }
084: if (sd.elements.size() == 1 && oldsd.elements.size() == 1) {
085: Object val = discValues.get(oldsd.elements.get(0));
086: discValues.put(sd.elements.get(0), val);
087: return;
088: }
089: for (Iterator it = oldsd.elements.iterator(); it.hasNext();) {
090: SpeedoElement oldse = (SpeedoElement) it.next();
091: if (oldse instanceof SpeedoNoFieldColumn) {
092: SpeedoNoFieldColumn snfc = (SpeedoNoFieldColumn) oldse;
093: SpeedoElement inheritedse = null;
094: for (Iterator it2 = sd.elements.iterator(); inheritedse == null
095: && it2.hasNext();) {
096: SpeedoElement currentse = (SpeedoElement) it2
097: .next();
098: if (currentse instanceof SpeedoNoFieldColumn) {
099: if (snfc.column.name
100: .equals(((SpeedoNoFieldColumn) currentse).column.name)) {
101: inheritedse = currentse;
102: }
103: } else if (currentse instanceof SpeedoField) {
104: if (snfc.column.name
105: .equals(((SpeedoField) currentse).columns[0].name)) {
106: inheritedse = currentse;
107: }
108: }
109: }
110: if (inheritedse != null) {
111: Object val = discValues.get(oldse);
112: discValues.put(inheritedse, val);
113: }
114: }
115: }
116: }
117:
118: private void checkColumn(SpeedoClass sc, SpeedoDiscriminator sd)
119: throws SpeedoException {
120: for (int i = 0; i < sd.elements.size(); i++) {
121: SpeedoElement se = (SpeedoElement) sd.elements.get(i);
122: if (se instanceof SpeedoNoFieldColumn) {
123: SpeedoColumn col = ((SpeedoNoFieldColumn) se).column;
124: SpeedoField sf = sc.getFieldFromColumn(col.name);
125: if (sf != null) {
126: // the specified column correspond to a primitive persistent
127: // field. Then the SpeedoNoFieldColumn is replaced by the
128: // the found field.
129: sd.elements.set(i, sf);
130: }
131: }
132: }
133: }
134: }
|