/**
* Copyright (C) 2001-2004 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.objectweb.speedo.generation.mivisitor;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.api.SpeedoProperties;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoExtension;
import org.objectweb.speedo.metadata.SpeedoIdentity;
import org.objectweb.speedo.metadata.SpeedoNoFieldColumn;
import org.objectweb.util.monolog.api.BasicLevel;
/**
*
* @author S.Chassande-Barrioz
*/
public class InheritanceVisitor
extends AbstractMetaInfoVisitor
implements SpeedoProperties {
private final static String DEFAULT_INHERITANCE_MAPPING
= INHERITANCE_FILTERED_MAPPING;
public InheritanceVisitor(Personality p) {
super(p);
}
protected String getLoggerName() {
return super.getLoggerName() + ".inheritance";
}
public void visitClass(SpeedoClass sc) throws SpeedoException {
if (sc.getSuperClassName() == null) {
sc.setSuperClassName(null);
super.visitClass(sc);
return;
}
//Always use the fully qualified name
SpeedoClass supersc = sc.getSpeedoClassFromContext(sc.getSuperClassName());
sc.setSuperClassName(supersc.getFQName());
if (debug) {
logger.log(BasicLevel.DEBUG, "class " + sc.getFQName()
+ " extends " + sc.getSuperClassName());
}
SpeedoExtension se = sc.getExtensionByKey(INHERITANCE_MAPPING);
if (se == null) {
se = new SpeedoExtension(VENDOR_NAME,
INHERITANCE_MAPPING,
DEFAULT_INHERITANCE_MAPPING, sc);
sc.addExtension(se);
}
//Assign identifier information to all familly member
List family = new ArrayList();
getFamily(sc, family);
SpeedoClass ancestor = (SpeedoClass) family.get(0);
List extensions = findExtensions(ancestor, new String[] {
ID, SQL_SEQ_ALLOCATOR, SQL_SEQ_CACHE, SQL_SEQ_INC, SQL_SEQ_NAME,
SQL_SEQ_START});
boolean detachable = ancestor.isDetachable;
SpeedoIdentity currentIdentity = ancestor.identity;
for(int i=1; i<family.size(); i++) {
SpeedoClass anAncestor = (SpeedoClass) family.get(i);
SpeedoNoFieldColumn[] cols = null;
if (anAncestor.identity != null) {
cols = anAncestor.identity.columns;
}
if (cols != null) {
anAncestor.identity.merge(ancestor.identity);
} else {
anAncestor.identity = ancestor.identity;
}
currentIdentity = anAncestor.identity;
//assign extensions from ancestor to subclasses
assignExtension(extensions, anAncestor);
//assign detachable attribute from ancestor to subclasses
detachable |= anAncestor.isDetachable;
if (!anAncestor.isDetachable && detachable) {
if (debug) {
logger.log(BasicLevel.DEBUG, "\tThe class " + anAncestor.name
+ " becomes detachable by inheritance.");
}
anAncestor.isDetachable = true;
}
}
super.visitClass(sc);
}
private List findExtensions(SpeedoClass sc, String[] keynames) {
ArrayList res = new ArrayList();
SpeedoExtension se;
for(int i=0; i<keynames.length; i++) {
se = sc.getExtensionByKey(keynames[i]);
if (se != null) {
res.add(se);
}
}
return res;
}
private void assignExtension(List extensions, SpeedoClass sc) {
for(int i=extensions.size()-1; i>=0; i--) {
SpeedoExtension se = (SpeedoExtension) extensions.get(i);
sc.addExtension(
new SpeedoExtension(se.vendorName, se.key, se.value, sc));
}
}
private void getFamily(SpeedoClass sc, List result) {
result.add(0, sc);
if (sc.getSuperClassName() == null) {
return;
}
SpeedoClass supersc = sc.getSpeedoClassFromContext(sc.getSuperClassName());
getFamily(supersc, result);
}
}