001: /**
002: * Copyright (C) 2001-2004 France Telecom R&D
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 2 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 org.objectweb.speedo.generation.mivisitor;
018:
019: import java.util.ArrayList;
020: import java.util.List;
021:
022: import org.objectweb.speedo.api.SpeedoException;
023: import org.objectweb.speedo.api.SpeedoProperties;
024: import org.objectweb.speedo.lib.Personality;
025: import org.objectweb.speedo.metadata.SpeedoClass;
026: import org.objectweb.speedo.metadata.SpeedoExtension;
027: import org.objectweb.speedo.metadata.SpeedoIdentity;
028: import org.objectweb.speedo.metadata.SpeedoNoFieldColumn;
029: import org.objectweb.util.monolog.api.BasicLevel;
030:
031: /**
032: *
033: * @author S.Chassande-Barrioz
034: */
035: public class InheritanceVisitor extends AbstractMetaInfoVisitor
036: implements SpeedoProperties {
037: private final static String DEFAULT_INHERITANCE_MAPPING = INHERITANCE_FILTERED_MAPPING;
038:
039: public InheritanceVisitor(Personality p) {
040: super (p);
041: }
042:
043: protected String getLoggerName() {
044: return super .getLoggerName() + ".inheritance";
045: }
046:
047: public void visitClass(SpeedoClass sc) throws SpeedoException {
048: if (sc.getSuperClassName() == null) {
049: sc.setSuperClassName(null);
050: super .visitClass(sc);
051: return;
052: }
053: //Always use the fully qualified name
054: SpeedoClass super sc = sc.getSpeedoClassFromContext(sc
055: .getSuperClassName());
056: sc.setSuperClassName(super sc.getFQName());
057: if (debug) {
058: logger.log(BasicLevel.DEBUG, "class " + sc.getFQName()
059: + " extends " + sc.getSuperClassName());
060: }
061: SpeedoExtension se = sc.getExtensionByKey(INHERITANCE_MAPPING);
062: if (se == null) {
063: se = new SpeedoExtension(VENDOR_NAME, INHERITANCE_MAPPING,
064: DEFAULT_INHERITANCE_MAPPING, sc);
065: sc.addExtension(se);
066: }
067: //Assign identifier information to all familly member
068: List family = new ArrayList();
069: getFamily(sc, family);
070: SpeedoClass ancestor = (SpeedoClass) family.get(0);
071: List extensions = findExtensions(ancestor, new String[] { ID,
072: SQL_SEQ_ALLOCATOR, SQL_SEQ_CACHE, SQL_SEQ_INC,
073: SQL_SEQ_NAME, SQL_SEQ_START });
074: boolean detachable = ancestor.isDetachable;
075: SpeedoIdentity currentIdentity = ancestor.identity;
076: for (int i = 1; i < family.size(); i++) {
077: SpeedoClass anAncestor = (SpeedoClass) family.get(i);
078: SpeedoNoFieldColumn[] cols = null;
079: if (anAncestor.identity != null) {
080: cols = anAncestor.identity.columns;
081: }
082: if (cols != null) {
083: anAncestor.identity.merge(ancestor.identity);
084: } else {
085: anAncestor.identity = ancestor.identity;
086: }
087: currentIdentity = anAncestor.identity;
088: //assign extensions from ancestor to subclasses
089: assignExtension(extensions, anAncestor);
090: //assign detachable attribute from ancestor to subclasses
091: detachable |= anAncestor.isDetachable;
092: if (!anAncestor.isDetachable && detachable) {
093: if (debug) {
094: logger.log(BasicLevel.DEBUG, "\tThe class "
095: + anAncestor.name
096: + " becomes detachable by inheritance.");
097: }
098: anAncestor.isDetachable = true;
099: }
100: }
101: super .visitClass(sc);
102: }
103:
104: private List findExtensions(SpeedoClass sc, String[] keynames) {
105: ArrayList res = new ArrayList();
106: SpeedoExtension se;
107: for (int i = 0; i < keynames.length; i++) {
108: se = sc.getExtensionByKey(keynames[i]);
109: if (se != null) {
110: res.add(se);
111: }
112: }
113: return res;
114: }
115:
116: private void assignExtension(List extensions, SpeedoClass sc) {
117: for (int i = extensions.size() - 1; i >= 0; i--) {
118: SpeedoExtension se = (SpeedoExtension) extensions.get(i);
119: sc.addExtension(new SpeedoExtension(se.vendorName, se.key,
120: se.value, sc));
121: }
122: }
123:
124: private void getFamily(SpeedoClass sc, List result) {
125: result.add(0, sc);
126: if (sc.getSuperClassName() == null) {
127: return;
128: }
129: SpeedoClass supersc = sc.getSpeedoClassFromContext(sc
130: .getSuperClassName());
131: getFamily(supersc, result);
132: }
133:
134: }
|