/**
* 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.naming.lib;
import org.objectweb.jorm.api.PClassMapping;
import org.objectweb.jorm.api.PException;
import org.objectweb.jorm.api.PMapper;
import org.objectweb.jorm.facility.naming.polymorphid.PolymorphIdBinderInfo;
import org.objectweb.jorm.facility.naming.polymorphid.PolymorphIdMgrImpl;
import org.objectweb.jorm.facility.naming.polymorphid.PolymorphIdPName;
import org.objectweb.jorm.facility.naming.polymorphid.PolymorphRefNC;
import org.objectweb.jorm.metainfo.api.Class;
import org.objectweb.jorm.metainfo.api.ClassMapping;
import org.objectweb.jorm.metainfo.api.ClassRef;
import org.objectweb.jorm.metainfo.api.CommonClassMapping;
import org.objectweb.jorm.metainfo.api.CompositeName;
import org.objectweb.jorm.metainfo.api.GenClassMapping;
import org.objectweb.jorm.metainfo.api.GenClassRef;
import org.objectweb.jorm.metainfo.api.Manager;
import org.objectweb.jorm.metainfo.api.MetaObject;
import org.objectweb.jorm.metainfo.api.NameDef;
import org.objectweb.jorm.metainfo.api.NameRef;
import org.objectweb.jorm.metainfo.api.PrimitiveElement;
import org.objectweb.jorm.metainfo.api.Reference;
import org.objectweb.jorm.naming.api.PBinder;
import org.objectweb.jorm.naming.api.PName;
import org.objectweb.jorm.naming.api.PNameCoder;
import org.objectweb.jorm.naming.api.PNamingContext;
import org.objectweb.jorm.type.api.PType;
import org.objectweb.jorm.type.api.PTypeSpace;
import org.objectweb.perseus.cache.api.CacheManager;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.api.SpeedoProperties;
import org.objectweb.speedo.generation.jorm.JormMIMappingBuilder;
import org.objectweb.speedo.mapper.api.JormFactory;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoColumn;
import org.objectweb.speedo.metadata.SpeedoExtension;
import org.objectweb.speedo.metadata.SpeedoField;
import org.objectweb.speedo.metadata.SpeedoIdentity;
import org.objectweb.speedo.naming.api.MIBuilderHelper;
import org.objectweb.speedo.naming.api.NamingManager;
import org.objectweb.speedo.pm.api.POManagerFactoryItf;
import org.objectweb.util.monolog.api.Logger;
import java.util.Collection;
import java.util.Map;
import java.util.Properties;
/**
*
* @author S.Chassande-Barrioz
*/
public class PolymorphIdNamingManager implements NamingManager {
/**
* is the name of the composite name used for the identifiers in case of
* container identifier management.
*/
private final static String POLYMORH_ID_NAME
= "org.objectweb.jorm.facility.naming.polymorphid.PolymorphId";
private final static String BINDER_CLASS_NAME
= POLYMORH_ID_NAME + "BinderInfo";
/**
* is a name of field of the composite name used for the identifiers in case of
* container identifier management.
*/
private final static String POLYMORH_ID_OID = "objectId";
/**
* is a name of field of the composite name used for the identifiers in case of
* container identifier management.
*/
private final static String POLYMORH_ID_CID = "classId";
private final static String OID = "oid";
private final static String CID = "cid";
/**
* The manager of the naming used by the container (long, long). It
* provides PBinder, PNamingContext since a class name.
*/
protected PolymorphIdMgrImpl cIdManager = null;
private PMapper mapper;
private Logger logger;
public PolymorphIdMgrImpl getcIdManager() throws PException {
if (cIdManager == null) {
cIdManager = new PolymorphIdMgrImpl();
cIdManager.setLogger(logger);
cIdManager.init(mapper, PClassMapping.CREATE_STRUCTURE_IF_NEEDED);
}
return cIdManager;
}
// IMPLEMENTATION OF THE METHOD FROM THE NamingManager INTERFACE //
//---------------------------------------------------------------//
public boolean supportPNamingcontext() {
return true;
}
public Object encode(PName pn) throws PException {
if (pn instanceof PolymorphIdPName) {
return pn.getPNameManager().getPType().getJormName()
+ SEP + pn.encodeString();
}
return null;
}
public PName decode(PNameCoder pnc, Object oid, java.lang.Class clazz, JormFactory jf) throws PException {
if (oid instanceof String) {
String stroid = (String) oid;
int idx = stroid.indexOf(SEP);
if (pnc != null) {
if (pnc instanceof PolymorphIdBinderInfo
|| pnc instanceof PolymorphRefNC) {
if (idx != -1) {
//The oid contains the class name
return pnc.decodeString(stroid.substring(idx + SEP.length()));
} else {
//The oid must decoded directly
return pnc.decodeString(stroid);
}
} else {
//The pnc is not a BasidBinder, then the oid cannot be managed
return null;
}
} else {
//No pnc specified
if (idx != -1) {
//The oid contains the class name
String fqcn = stroid.substring(0, idx);
ClassLoader cl = getClass().getClassLoader();
if (cl == null) {
cl = ClassLoader.getSystemClassLoader();
}
try {
pnc = jf.getPBinder(fqcn, cl);
} catch (Exception e) {
}
return (pnc instanceof PolymorphIdBinderInfo
|| pnc instanceof PolymorphRefNC
? pnc.decodeString(stroid.substring(idx + SEP.length()))
: null);
} else {
//The oid cannot be managed
return null;
}
}
}
return null;
}
public void setPMapper(PMapper mapper) {
this.mapper = mapper;
}
public void setPmf(POManagerFactoryItf pmf) {
}
public void setLogger(Logger logger) {
this.logger = logger;
}
public boolean canManage(SpeedoClass sc) {
return sc.identity.strategy == SpeedoIdentity.DATASTORE_POLYMORPHID;
}
public boolean canProvidePBinder(Object hints, ClassLoader classLoader) {
return BINDER_CLASS_NAME.equals(hints);
}
public boolean canProvidePNamingContext(Object hints, ClassLoader classLoader) {
return canProvidePBinder(hints, classLoader);
}
public PBinder getPBinder(String className,
String hints,
ClassLoader classLoader,
byte mappingStructureRule,
Map cn2binder,
Map cn2pnc) throws PException {
return getcIdManager().getPBinder(className);
}
public PNamingContext getPNamingContext(String className,
String hints,
ClassLoader classLoader,
byte mappingStructureRule,
Map cn2binder,
Map cn2pnc,
Manager miManager,
PClassMapping pcm) throws PException {
return getcIdManager().getRefNC(className);
}
private void defineNameDef(NameDef nd,
MetaObject owner,
MIBuilderHelper mibh,
String prefix) throws SpeedoException, PException{
PrimitiveElement oid = mibh.createNameDefField(owner, prefix + OID, PTypeSpace.LONG);
PrimitiveElement cid = mibh.createNameDefField(owner, prefix + CID, PTypeSpace.LONG);
Manager manager = mibh.getManager(owner);
CompositeName speedoidcn = getPolymorphIdCN(manager);
NameRef nr = nd.createNameRef(speedoidcn);
nr.addProjection(POLYMORH_ID_OID, oid.getName());
nr.addProjection(POLYMORH_ID_CID, cid.getName());
}
public void defineClassIdentifierNameDef(NameDef nd,
Class jc,
SpeedoClass sc,
ClassMapping cm,
MIBuilderHelper mibh,
JormMIMappingBuilder mb,
Collection createdMOs) throws SpeedoException, PException {
defineNameDef(nd, jc, mibh, "");
mb.createClassIdentifierNameDefMapping(cm, nd, sc, mibh);
}
public void defineClassReferenceNameDef(NameDef nd,
ClassRef cr,
SpeedoField sf,
SpeedoClass currentClass,
ClassMapping cm,
MIBuilderHelper mibh,
JormMIMappingBuilder mb) throws SpeedoException, PException {
String prefix = mibh.getNameDefFieldPrefix(cr, false, false, sf);
defineNameDef(nd, cr.getParent(), mibh, prefix);
mb.createClassRefNameDefMapping(cm, nd, sf);
}
public void defineClassReferenceNameDef(NameDef nd, ClassRef cr,
SpeedoField sf, SpeedoClass currentClass, GenClassMapping gcm,
MIBuilderHelper mibh, JormMIMappingBuilder mb)
throws SpeedoException, PException {
String prefix = mibh.getNameDefFieldPrefix(cr, false, true, sf);
defineNameDef(nd, cr.getParent(), mibh, prefix);
mb.createClassRefNameDefMapping(gcm, nd, sf);
}
public void defineGenClassIdentifierNameDef(NameDef nd,
GenClassRef gcr,
SpeedoField sf,
SpeedoClass currentClass,
GenClassMapping gcm,
MIBuilderHelper mibh,
JormMIMappingBuilder mb) throws SpeedoException, PException {
defineNameDef(nd, gcr, mibh, "");
mb.createGenClassIdentifierNameDefMapping(gcm, nd, sf, mibh);
}
public void defineGenClassReferenceNameDef(NameDef nd,
GenClassRef gcr,
SpeedoField sf,
SpeedoClass currentClass,
ClassMapping cm,
MIBuilderHelper mibh,
JormMIMappingBuilder mb)
throws SpeedoException, PException {
//The polymorph id does not support the mapping
// where the GC id is the source class id
// then the field name contains the GCR name as prefix
String prefix = gcr.getName() + "_";
defineNameDef(nd, gcr, mibh, prefix);
mb.createGenClassRefNameDefMapping(cm, nd, sf);
}
public boolean needInheritanceDiscriminator(SpeedoClass sc)
throws SpeedoException {
return false;
}
private CompositeName getPolymorphIdCN(Manager manager) {
CompositeName cn = manager.getCompositeName(POLYMORH_ID_NAME);
if (cn == null) {
cn = manager.createCompositeName(POLYMORH_ID_NAME);
cn.createCompositeNameField(POLYMORH_ID_CID, PTypeSpace.LONG, PType.NOSIZE, PType.NOSIZE);
cn.createCompositeNameField(POLYMORH_ID_OID, PTypeSpace.LONG, PType.NOSIZE, PType.NOSIZE);
}
return cn;
}
public void getJormNamingConfig(NameDef nd,
SpeedoClass targetClass,
MetaObject sourceMO,
String key,
Properties result) {
result.setProperty(key, BINDER_CLASS_NAME);
}
public String getPNameHints(SpeedoClass sc, NameDef nd) {
return "null";
}
public Object[] getPNameHints2(SpeedoClass sc, NameDef nd) {
return new Object[]{PNH_NULL_VALUE};
}
public String getGCPNameHints(SpeedoClass sc, NameDef nd) {
return "null";
}
public NamingManager.NamingField[] getNamingfields(SpeedoClass sc) {
return null;
}
public SpeedoColumn[] getDefaultColumn(SpeedoClass sc) {
SpeedoColumn[] cols = new SpeedoColumn[] {
new SpeedoColumn(), new SpeedoColumn()};
cols[0].name = CID;
cols[0].targetField = CID;
cols[1].name = OID;
cols[1].targetField = OID;
return cols;
}
public void setCache(CacheManager cache) {
}
}