Package org.objectweb.speedo.naming.lib

Source Code of org.objectweb.speedo.naming.lib.CommonLongIdNamingManager

/**
* 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 java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.objectweb.jorm.api.PClassMapping;
import org.objectweb.jorm.api.PException;
import org.objectweb.jorm.api.PMapper;
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.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.ScalarField;
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.medor.expression.api.Expression;
import org.objectweb.medor.expression.api.ExpressionException;
import org.objectweb.medor.expression.lib.BasicOperand;
import org.objectweb.medor.expression.lib.BasicParameterOperand;
import org.objectweb.medor.expression.lib.DivideBy;
import org.objectweb.medor.expression.lib.Round;
import org.objectweb.perseus.cache.api.CacheManager;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.generation.jorm.JormMIMappingBuilder;
import org.objectweb.speedo.generation.lib.NamingRules;
import org.objectweb.speedo.mapper.api.JormFactory;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoColumn;
import org.objectweb.speedo.metadata.SpeedoField;
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.BasicLevel;
import org.objectweb.util.monolog.api.Logger;

/**
* Defines a common implementation of NamingManager for identifier based on
* a single long or java.lang.Long field.
*
* @author S.Chassande-Barrioz
*/
public abstract class CommonLongIdNamingManager
  extends NamingManagerHelper {

  /**
   * @return the name of the composite name (JORM object) corresponding the
   * identifier.
   */
  protected abstract String getLongIdName();
  /**
   * @return the default name of the identifier field.
   */
  protected abstract String getLongIdLid();
  /**
   * @return the default jorm type of the identifier field.
   */
  protected abstract PType getFieldType();
  /**
   * @return the default java type of the identifier field.
   */
  protected abstract java.lang.Class getJavaFieldType();
  /**
   * @return the operand (Medor object) used for computing the class identifier
   */
  protected abstract BasicOperand getBasicOperand();
  /**
   * Checks if the field type is the one expected
   * @param type is the field type as a string.
   * @return true if this the right type.
   */
  protected abstract boolean checkFieldType(String type);
  /**
   * @return the mapper used
   */
  public abstract PMapper getMapper();
  /**
   * @return a new PBinder for managing GenClass identifier.
   */
  public abstract PBinder newGenClassPBinder() throws PException;
  /**
   * @param className is the class name of the persistent class
   * @param conn is the connection to the underlying persistent support.
   * @return a new PBinder for managing class identifier.
   */
  public abstract PBinder newClassPBinder(String className, Object conn) throws PException;
  /**
   * @return a new PBinder for managing class reference.
   */
  public abstract PNamingContext newClassPNamingContext() throws PException;
  /**
   * @return the class of the PName used by this naming.
   */
  public abstract java.lang.Class getPNameClass();
  /**
   * @return the class of the PBinder used by this naming.
   */
  public abstract java.lang.Class getPBinderClass();
  /**
   * @return the class of the IdManager used by this naming.
   */
  public abstract java.lang.Class getLongIdManagerClass();
  /**
   * @return the class of the PNamingContext used by this naming.
   */
  public abstract java.lang.Class getPNamingContextClass();
  /**
   * Decodes a string value into a PName.
   * @param pnc is the PNameCoder able to decode the string
   * @param idStr is the string representation of an identifier
   * @return a PName
   */
  protected abstract PName decodeLong(PNameCoder pnc, String idStr) throws PException;
  /**
   * Encodes a PName into a value.
   * @param pn is the PName to encode
   * @return the encoded PName
   */
  public abstract Object encode(PName pn) throws PException; 

  /**
     * @return Returns the bINDER_FOR_GENCLASS.
     */
  protected abstract String getBinderForGenClass();
    /**
     * @return Returns the bINDER_FOR_CLASS.
     */
  protected abstract String getBinderForClass();
    /**
     * @return Returns the hIDDEN_LID_FIELD_NAME.
     */
    protected abstract String getHiddenLidFieldName();
 
  public void init() throws PException {
    if (getMapper() != null) {
      return;
    }
    if (mapper == null) {
      throw new PException("No mapper assigned");
    }
    setPMapper(mapper);
    mapper = null;
  }

  // IMPLEMENTATION OF THE METHOD FROM THE NamingManager INTERFACE //
  //---------------------------------------------------------------//
  public void setPmf(POManagerFactoryItf pmf) {
  }
  public boolean supportPNamingcontext() {
    return true;
  }
  public abstract boolean canManage(SpeedoClass sc);
 
  public boolean canProvidePBinder(Object hints, ClassLoader classLoader) {
    return getBinderClassNameFromHints(hints, getName()) != null;
  }
  public boolean canProvidePNamingContext(Object hints, ClassLoader classLoader) {
    return getPNCClassNameFromHints(hints, getName()) != 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 (getPBinderClass().isInstance(pnc)
                        || getLongIdManagerClass().isInstance(pnc)) {
          String idStr = stroid;
                    if (idx != -1) {
                        //The oid contains the class name
            idStr = stroid.substring(idx + SEP.length());
                    }
          return decodeLong(pnc, idStr);

                } else {
                    //The pnc is not a well known pnc, 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.getPNamingContext(fqcn, cl);
                    } catch (Exception e) {
            return null;
                    }
                    if (getPBinderClass().isInstance(pnc)
                            || getPNamingContextClass().isInstance(pnc)) {
            return decodeLong(pnc,
                    stroid.substring(idx + SEP.length()));
          } else {
            return null;
          }
                } else {
                    //The oid cannot be managed
                    return null;
                }
            }
        }
        return null;
    }
    public void setLogger(Logger logger) {
        this.logger = logger;
    }
    public String getPNameHints(SpeedoClass sc, NameDef nd) {
        return "null";
    }
    public Object[] getPNameHints2(SpeedoClass sc, NameDef nd) {
        return new Object[]{PNH_NULL_VALUE};
    }
    public NamingManager.NamingField[] getNamingfields(SpeedoClass sc) {
        SpeedoField sf;
        try {
            sf = sc.getUniquePKField();
        } catch (SpeedoException e) {
            sf = null;
        }
        if (sf != null) {
      return new NamingManager.NamingField[]{
          new NamingManager.NamingField(
                  sf.name, getJavaFieldType(), getLongIdLid(), getFieldType())};
    } else {
        return null;
    }
    }
    public void defineClassIdentifierNameDef(NameDef nd,
            Class jc,
            SpeedoClass sc,
            ClassMapping cm,
            MIBuilderHelper mibh,
            JormMIMappingBuilder mb,
            Collection createdMOs)
            throws SpeedoException, PException {
    SpeedoField pkField = fetchUniqueLongPKField(sc);
    PrimitiveElement lid;
    String lidname;
    if (pkField == null) {
        if (sc.identity.columns == null) {
            logger.log(BasicLevel.WARN,
                    "No mapping information for the identifier of the class '"
                    + sc.getFQName() +"'.");
          lidname = getHiddenLidFieldName();
        } else {
            lidname = sc.identity.columns[0].column.name;
        }
        // create an hidden identifier field
      lid = mibh.createNameDefField(sc.jormclass, lidname, getFieldType());
    } else {
        //The identifier is mapped over a persistent field
        lidname = pkField.name;
      lid = mibh.getPrimitiveField(sc.jormclass, lidname);
      if (lid == null) {
        throw new SpeedoException(
          mibh.getErrorMessage(sc, sc.jormclass, null)
          + " Impossible to get the field '" + lidname + "'");
      }
    }
        Manager manager = mibh.getManager(jc);
        CompositeName cn = getLongIdCompositeName(manager);
    NameRef nr = nd.createNameRef(cn);
    nr.addProjection(getLongIdLid(), lid.getName());
    if (sc.jormclass.getSuperClasses().isEmpty()) {
      // define the inheritance filter permiting to determine the class
      // since an identifier (some bits are reserved for class
      // identification)
      Expression expr = new Round(new DivideBy(
        new BasicParameterOperand(getFieldType(), getLongIdLid()),
        getBasicOperand()));
      try {
        expr.compileExpression();
      } catch (ExpressionException e) {
        throw new SpeedoException("Impossible to compile the filter of longid naming", e);
      }
      sc.jormclass.setInheritanceFilter(nd, expr);
        // assign a default value to each sub classes. The real value
      // is computed at runtime from the database content.
      assignDummyKeyToFamilly(sc.jormclass, nd);
    }
    if (pkField == null) {
        mb.createClassIdentifierNameDefMapping(cm, nd, sc, mibh);
    }
    }
    public boolean needInheritanceDiscriminator(SpeedoClass sc)
      throws SpeedoException {
        return false;
    }

    public void defineClassReferenceNameDef(NameDef nd,
            ClassRef cr,
            SpeedoField sf,
            SpeedoClass currentClass,
            ClassMapping cm,
            MIBuilderHelper mibh,
            JormMIMappingBuilder mb) throws SpeedoException, PException {
    String lidname = mibh.getNameDefFieldPrefix(cr, false, false, sf)
      + getHiddenLidFieldName();
        SpeedoClass referencedClass = sf.moClass.getSpeedoClassFromContext(
                cr.getMOClass().getFQName());
        //get the composite name
        Manager manager = mibh.getManager(cr);
        CompositeName cn = getLongIdCompositeName(manager);
    NameRef nr = nd.createNameRef(cn);
    //create the hidden field
    mibh.createNameDefField(cr.getParent(), lidname, getFieldType());
    //define translation betwen the composite name field and the hidden field
    nr.addProjection(getLongIdLid(), lidname);
    //map the created hidden field in the ClassMapping
      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 lidname = mibh.getNameDefFieldPrefix(cr, false, true, sf)
      + getHiddenLidFieldName();
        SpeedoClass referencedClass = sf.moClass.getSpeedoClassFromContext(
                cr.getMOClass().getFQName());
        //get the composite name
    Manager manager = mibh.getManager(cr);
        CompositeName cn = getLongIdCompositeName(manager);
    NameRef nr = nd.createNameRef(cn);
    //create the hidden field
    mibh.createNameDefField(cr.getParent(), lidname, getFieldType());
    //define translation betwen the composite name field and the hidden field
    nr.addProjection(getLongIdLid(), lidname);
    //map the created hidden field in the GenClassMapping
      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 {
    String lidname = mibh.getNameDefFieldPrefix(gcr, true, true, sf)
      + getHiddenLidFieldName();
    mibh.createNameDefField(gcr, lidname, getFieldType());
    //Gen class identifier is based on basid
    nd.setFieldName(lidname);
    //map the created hidden field in the GenClassMapping
      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 {
        SpeedoField pkfield = sf.moClass.getUniquePKField();
        String fn;
        if (pkfield == null) {
            fn = getHiddenLidFieldName();
        } else {
            fn = pkfield.name;
        }
    //Gen class reference is based on basid
    nd.setFieldName(fn);
    }
  private CompositeName getLongIdCompositeName(Manager manager) {
    CompositeName cn = manager.getCompositeName(getLongIdName());
    if (cn == null) {
      cn = manager.createCompositeName(getLongIdName());
      ScalarField cnf = cn.createCompositeNameField(
        getLongIdLid(), getFieldType(), PType.NOSIZE, PType.NOSIZE);
      cnf.setIsAutoCalculated(true);
    }
    return cn;
  }
  private void assignDummyKeyToFamilly(org.objectweb.jorm.metainfo.api.Class clazz, NameDef nd) {
    clazz.setInheritanceNamingKey(nd, "0");
    for(Iterator it = clazz.getSubClasses().iterator(); it.hasNext();) {
      assignDummyKeyToFamilly(((org.objectweb.jorm.metainfo.api.Class) it.next()), nd);
    }
  }
  private SpeedoField fetchUniqueLongPKField(SpeedoClass tsc) throws SpeedoException {
    Iterator it = tsc.fields.values().iterator();
    SpeedoField sf = null;
    ArrayList al = null;
    while (it.hasNext()) {
      SpeedoField _sf = (SpeedoField) it.next();
      if (_sf.primaryKey) {
        if (sf != null) {
          if (al == null) {
            al = new ArrayList();
          }
          al.add(_sf.name);
        } else {
          sf = _sf;
        }
      }
    }
    if (al != null) {
      al.add(sf);
      throw new SpeedoException(
        "Impossible to use an auto incremented identifier if " +
        "several fields have been marked as primary-key " + al
        + " in the class '" + tsc.getFQName() + "'.");
    }
    if (sf != null) {
        String t = sf.type();
       
      if (!checkFieldType(t)) {
        throw new SpeedoException(
          "Impossible to use an auto incremented identifier: " +
          "the field type of '" + sf.name + "' is '" + sf.type()
          + "' and '" + getFieldType().getJavaName()
          + "' is expected (class '"
          + tsc.getFQName() + "'.");
      }
    }
    return sf;
  }
  public void getJormNamingConfig(NameDef nd,
                  SpeedoClass targetClass,
                  MetaObject sourceMO,
                  String key,
                  Properties result) {

    StringBuffer sb = new StringBuffer();
    sb.append(getName());
    sb.append(NamingManagerHelper.HINTS_SEP);
    boolean isGCR = sourceMO instanceof GenClassRef;
    String binderInfo = (isGCR ? getBinderForGenClass() : getBinderForClass());
    sb.append(binderInfo);

    SpeedoClass ancestor = targetClass.getAncestor();
    String ancestorClassName;
    String pncClassName;
    if (!isGCR //For a Genclass ref or genclass identifier
      && (ancestor != null // has supper class
        || !targetClass.jormclass.getSubClasses().isEmpty()) // has sub class
      ) {
      if (ancestor == null) {
        ancestor = targetClass;
      }
      ancestorClassName = ancestor.getFQName();
      pncClassName = NamingRules.kfpncName(ancestorClassName);
    } else {
      ancestorClassName = targetClass.getFQName();
      pncClassName = binderInfo;
    }
    //specify the pnc className
    sb.append(NamingManagerHelper.HINTS_SEP);
    sb.append(pncClassName);

    //specify the className of the ancestor
    sb.append(NamingManagerHelper.HINTS_SEP);
    sb.append(ancestorClassName);
    result.setProperty(key, sb.toString());
    }
  public PBinder getPBinder(String className,
                String hints,
                ClassLoader classLoader,
                byte mappingStructureRule,
                Map cn2binder,
                Map cn2pnc) throws PException {
    init();
    String binderInfo = getBinderClassNameFromHints(hints, getName());
    return getPBinder(className, binderInfo);
  }
  public PNamingContext getPNamingContext(String className,
                      String hints,
                      ClassLoader classLoader,
                      byte mappingStructureRule,
                      Map cn2binder,
                      Map cn2pnc,
                      Manager miManager,
                      PClassMapping pcm) throws PException {
    init();
    String[] tokens = NamingManagerHelper.getTokens(hints);
    PNamingContext pnc = null;
    if (tokens[NamingManagerHelper.BINDER_IDX].equals(tokens[NamingManagerHelper.PNC_IDX])) {
      //The binder must be used as PNamingContext
      pnc = (PNamingContext) cn2binder.get(className);
      if (pnc == null) {
        //instanciate the binder/PNC
        pnc = (PNamingContext) getPBinder(
          className, tokens[NamingManagerHelper.BINDER_IDX]);
        //register the binder/PNC as binder
        cn2binder.put(className, pnc);
      }
      return pnc;
    } else {
      boolean register = false;
      if (!tokens[NamingManagerHelper.PCLASS_IDX].equals(className)) {
        //The PNC of THE ancestor must be used
        pnc = (PNamingContext) cn2pnc.get(tokens[NamingManagerHelper.PCLASS_IDX]);
        if (pnc == null) {
          register = true;
        }
      }
      if (pnc == null) {
        //instanciate the PNC
        pnc = newClassPNamingContext();
        if (register) {
          cn2pnc.put(tokens[NamingManagerHelper.PCLASS_IDX], pnc);
        }
      }
    }
    return pnc;
  }
  protected PBinder getPBinder(String className, String binderInfo) throws PException {
    if (binderInfo.startsWith(getBinderForGenClass())) {
      return newGenClassPBinder();
    } else if (binderInfo.startsWith(getBinderForClass())) {
      return newClassPBinder(className, null);
    } else {
      throw new PException("Bad binder info: " + binderInfo);
    }
  }
  public void setCache(CacheManager cache) {
  }
    public SpeedoColumn[] getDefaultColumn(SpeedoClass sc) {
        return new SpeedoColumn[] {new SpeedoColumn(getHiddenLidFieldName())};
    }
}
TOP

Related Classes of org.objectweb.speedo.naming.lib.CommonLongIdNamingManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.