Package org.objectweb.speedo.naming.lib

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

/**
* 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.PException;
import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequenceBinder;
import org.objectweb.jorm.facility.naming.rdbsequence.RdbSequencePName;
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.GenClassMapping;
import org.objectweb.jorm.metainfo.api.GenClassRef;
import org.objectweb.jorm.metainfo.api.MetaObject;
import org.objectweb.jorm.metainfo.api.NameDef;
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.type.api.PType;
import org.objectweb.jorm.type.api.PTypeSpace;
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.metadata.SpeedoIdentity;
import org.objectweb.speedo.naming.api.MIBuilderHelper;
import org.objectweb.speedo.naming.api.NamingManager;
import org.objectweb.speedo.sequence.api.SpeedoSequenceItf;
import org.objectweb.speedo.sequence.lib.SpeedoSequenceBinder;
import org.objectweb.speedo.tools.StringReplace;
import org.objectweb.util.monolog.api.BasicLevel;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

/**
* This is naming manager manages identifier based sequence in database (SQL
* sequence or simple counter managed by Speedo).
* This identifier can be mapped over a persistent field (type must be long or
* java.lang.Long). This identifier format does not support polymorphism directly.
* You have to specify discriminator(s). But in all case, this naming is not an
* efficient choice when there is polymorphism (ex inheritance). Indeed SQL request
* to find a corresponding object is more complex. The null reference depends on
* the field type: -1 for long field and NULL or java.lang.Long field type.
*
* @see org.objectweb.speedo.naming.api.NamingManager
* @see org.objectweb.speedo.sequence.lib.SpeedoSequence
* @see org.objectweb.speedo.sequence.lib.SpeedoSequenceBinder
* @see org.objectweb.jorm.facility.naming.rdbsequence.RdbSequenceBinder
* @author S.Chassande-Barrioz
*/
public class RdbSequenceNamingManager
  extends NamingManagerHelper
  implements NamingManager {
    private final static String ID_FIELD ="id_";

    private final static String SEQUENCE_ID ="sid";
    private final static String SPEEDO_BINDER_CLASS_NAME
      = SpeedoSequenceBinder.class.getName();
    public final static int SEQ_NAME_IDX       = 4;
  public final static int SEQ_INCREMENT_IDX     = 5;
  public final static int SEQ_STARTID_IDX     = 6;
  public final static int SEQ_CACHE_IDX       = 7;
  public final static int SEQ_ALLOCATOR_IDX     = 8;



    public boolean canManage(SpeedoClass sc) {
      if (sc.identity.strategy == SpeedoIdentity.DATASTORE_SEQUENCE) {
        return true;
      }
      return false;
    }

    // IMPLEMENTATION OF THE METHOD FROM THE NamingManager INTERFACE //
    //---------------------------------------------------------------//

    public PName decode(PNameCoder pnc,
                        Object oid,
                        java.lang.Class clazz,
                        JormFactory jf) throws PException {
        if (oid instanceof String) {
            String stroid = (String) oid;
            if (pnc != null) {
                if (pnc instanceof RdbSequenceBinder) {
          int idx = stroid.indexOf(SEP);
                    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 RdbSequenceBinder, then the oid cannot be managed
                    return null;
                }
            } else {
                //No pnc specified
        int idx = stroid.indexOf(SEP);
              ClassLoader cl = null;
              String fqcn;
                if (idx != -1) {
                    //The oid contains the class name
                    fqcn = stroid.substring(0, idx);
                } else if (clazz != null) {
                  fqcn = clazz.getName();
                } else {
                  //The oid cannot be managed
                  return null;
                }
        cl = jf.getClass().getClassLoader();
        if (cl == null) {
          cl = ClassLoader.getSystemClassLoader();
        }
        try {
          pnc = jf.getPBinder(fqcn, cl);
        } catch (Exception e) {
          return null;
        }
        return (pnc instanceof RdbSequenceBinder
          ? pnc.decodeString(stroid.substring(idx + SEP.length()))
          : null);
            }
        } else if (pnc instanceof RdbSequenceBinder){
            if (oid instanceof Integer) {
                pnc.decodeLong(((Integer) oid).intValue());
            } else if (oid instanceof Long) {
                pnc.decodeLong(((Long) oid).longValue());
            }
        }
        return null;
    }

    public Object encode(PName pn) throws PException {
        if (pn instanceof RdbSequencePName) {
            return pn.getPNameManager().getPType().getJormName()
                    + SEP + pn.encodeString();
        }
        return null;
    }

  protected String getName() {
    return SEQUENCE_ID;
  }

    public PBinder getPBinder(String className,
                String hints,
                ClassLoader cl,
                byte mappingStructureRule,
                              Map cn2binder,
                              Map cn2pnc) throws PException {
      SpeedoSequenceBinder binder = (SpeedoSequenceBinder) super.getPBinder(
      className, hints, cl, mappingStructureRule, cn2binder, cn2pnc);
      String[] tokens = getTokens(hints);
    if (tokens[SEQ_NAME_IDX].length() > 0) {
      if (logger != null && logger.isLoggable(BasicLevel.DEBUG)) {
        logger.log(BasicLevel.DEBUG, "Sequence name: " + tokens[SEQ_NAME_IDX]);
      }
      String sequencePrefix = (className.lastIndexOf('.') != -1) ? className.substring(0, className.lastIndexOf('.')+1):"";
      sequencePrefix = StringReplace.replaceString("/", "", sequencePrefix);
      SpeedoSequenceItf sequence = (SpeedoSequenceItf) pmf.getSequenceManager()
        .getSequence(sequencePrefix + tokens[SEQ_NAME_IDX]);
      if (sequence == null) {
        throw new PException("Wrong sequence name: " + sequencePrefix + tokens[SEQ_NAME_IDX]);
      }
      sequence.getLongGen();
      binder.setSequence(sequence);
    }
        return binder;
    }

  public void getJormNamingConfig(NameDef nd,
                  SpeedoClass targetClass,
                  MetaObject sourceMO,
                  String key,
                  Properties result) throws SpeedoException{
      StringBuffer sb = new StringBuffer();
    sb.append(SEQUENCE_ID);

    sb.append(HINTS_SEP);
    sb.append(SPEEDO_BINDER_CLASS_NAME);

    SpeedoClass ancestor = targetClass.getAncestor();
    String ancestorClassName;
    String pncClassName;
    if (!(sourceMO instanceof GenClassRef) //For a Genclass ref or identifier
      && (ancestor != null // has supper class
        || !targetClass.jormclass.getSubClasses().isEmpty()) // has sub class
      ) {
      if (ancestor == null) {
        ancestor = targetClass;
      }
      ancestorClassName = ancestor.getFQName();
      try {
        if (targetClass.jormclass.getSubClasses().isEmpty()) {
          pncClassName = SPEEDO_BINDER_CLASS_NAME;
        } else   if (targetClass.jormclass.detectFilterElementNotInPK(targetClass.jormclass.getInheritanceFilter(nd), nd)) {
          //if has child(ren)
          //and one of the fields of the filter is not in the primary key,
          //use a PolymorphicPNC
          pncClassName = POLYMORPHIC_PNC;
        } else {
          //use a kfpnc
          pncClassName = NamingRules.kfpncName(ancestor.getFQName());
        }
      } catch (Exception e) {
        logger.log(BasicLevel.ERROR, "Error while retrieving the inheritance filter of the namedef:" + nd.toString());
        throw new SpeedoException("Error while retrieving the inheritance filter of the namedef:" + nd.toString(), e);
      }
    } else {
      ancestorClassName = targetClass.getFQName();
      pncClassName = SPEEDO_BINDER_CLASS_NAME;
    }
    //specify the pnc className
    sb.append(HINTS_SEP);
    sb.append(pncClassName);

    //specify the className of the ancestor
    sb.append(HINTS_SEP);
    sb.append(ancestorClassName);

      //sequence name
      sb.append(HINTS_SEP);
      sb.append(targetClass.identity.sequenceName);
        result.setProperty(key, sb.toString());
     }

    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 "speedoPO.getPName()";
    }

    public void defineClassIdentifierNameDef(NameDef nd,
            Class jc,
            SpeedoClass sc,
            ClassMapping cm,
            MIBuilderHelper mibh,
            JormMIMappingBuilder mb,
            Collection createdMOs) throws SpeedoException, PException {
        SpeedoField pkField = sc.getUniquePKField();
        String fieldName;
    if (pkField == null) {
        if (sc.identity.columns == null) {
            logger.log(BasicLevel.WARN,
                    "No mapping information for the identifier of the class '"
                    + sc.getFQName() +"'.");
              fieldName = ID_FIELD;
        } else {
            fieldName = sc.identity.columns[0].column.name;
        }
            mibh.createNameDefField(jc, fieldName, PTypeSpace.OBJLONG);
        } else {
            String type = pkField.type();
      if (!"java.lang.Long".equals(type) && !"Long".equals(type)
                    && !"long".equals(type)) {
                throw new SpeedoException(
                        "Impossible to use an auto incremented identifier: " +
                        "the field type of '" + pkField.name + "' is '" + pkField.type()
                        + "' and 'java.lang.Long' or long is expected (class '"
                        + sc.getFQName() + "'.");
            }
            fieldName = pkField.name;
        }
        nd.setFieldName(fieldName);
        if (pkField == null) {
            mb.createClassIdentifierNameDefMapping(cm, nd, sc,mibh);
        }
    }
    private void defineClassReferenceNameDef(NameDef nd,
            ClassRef cr,
            SpeedoField sf,
            MIBuilderHelper mibh,
            String prefix) throws SpeedoException, PException {
        SpeedoClass referencedClass = sf.moClass.getSpeedoClassFromContext(
                cr.getMOClass().getFQName());
        SpeedoField pkField = (SpeedoField) referencedClass.getUniquePKField();
        String fieldName = null;
        PType fieldType;
    if (pkField == null) {
            fieldName = ID_FIELD;
            fieldType = PTypeSpace.OBJLONG;
        } else {
            String type = pkField.type();
      if ("java.lang.Long".equals(type) || "Long".equals(type)) {
        fieldType = PTypeSpace.OBJLONG;
      } else if ("long".equals(type)) {
        fieldType = PTypeSpace.LONG;
      } else {
                throw new SpeedoException(
                        "Impossible to use an auto incremented identifier: " +
                        "the field type of '" + pkField.name + "' is '" + pkField.type()
                        + "' and 'java.lang.Long' or long is expected (class '"
                        + pkField.moClass.getFQName() + "'.");
            }
            fieldName = pkField.name;
        }
    fieldName = prefix + fieldName;
        mibh.createNameDefField(cr.getParent(), fieldName, fieldType);
        nd.setFieldName(fieldName);
       
    }
    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);
        defineClassReferenceNameDef(nd, cr, sf, 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);
        defineClassReferenceNameDef(nd, cr, sf, mibh, prefix);
        mb.createClassRefNameDefMapping(gcm, nd, sf);
    }
    private void defineGenClassNameDef(NameDef nd,
            GenClassRef gcr,
            SpeedoField sf,
            MIBuilderHelper mibh,
            boolean isGCId) throws SpeedoException, PException {
        //Find the unique pkField in order to get its name and its type
        String fieldName;
        PType fieldType;
        SpeedoField pkField = sf.moClass.getUniquePKField();
        if (isGCId) {
            //create hidden field in the GenClassRef for its identifier
            // the create field has a name built from the GCR name itself
        if (pkField == null) {
            //there is no pk field defined ==> new one
                fieldName = ID_FIELD;
                fieldType = PTypeSpace.OBJLONG;
            } else {
                fieldName = pkField.name;
                //Check the PK field type (Long or long only supported)
                String type = pkField.type();
          if ("java.lang.Long".equals(type) || "Long".equals(type)) {
            fieldType = PTypeSpace.OBJLONG;
          } else if ("long".equals(type)) {
            fieldType = PTypeSpace.LONG;
          } else {
                    throw new SpeedoException(
                            "Impossible to use an auto incremented identifier: " +
                            "the field type of '" + pkField.name + "' is '" + pkField.type()
                            + "' and 'java.lang.Long' or long is expected (class '"
                            + pkField.moClass.getFQName() + "'.");
                }
            }
            String prefix = mibh.getNameDefFieldPrefix(gcr, isGCId, isGCId, sf);
        fieldName = prefix + fieldName;
            mibh.createNameDefField(gcr, fieldName, fieldType);
        } else {
            // In case of reference to a generic class, the pkfield of the
            // current class is used
        if (pkField == null) {
            //there is no pk field defined ==> new one
                fieldName = ID_FIELD;
            } else {
                fieldName = pkField.name;
            }
        }
        nd.setFieldName(fieldName);
    }
           
    public void defineGenClassIdentifierNameDef(NameDef nd,
            GenClassRef gcr,
            SpeedoField sf,
            SpeedoClass currentClass,
            GenClassMapping gcm,
            MIBuilderHelper mibh,
            JormMIMappingBuilder mb) throws SpeedoException, PException {
        defineGenClassNameDef(nd, gcr, sf, mibh, true);
        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 {
        defineGenClassNameDef(nd, gcr, sf, mibh, false);
    }

    public NamingField[] getNamingfields(SpeedoClass sc) throws PException {
        Iterator it = sc.fields.values().iterator();
        while(it.hasNext()) {
            SpeedoField sf = (SpeedoField) it.next();
            if (sf.primaryKey) {
        java.lang.Class fieldType;
        PType fieldPType;
        if ("java.lang.Long".equals(sf.type()) || "Long".equals(sf.type())) {
          fieldType = Long.class;
          fieldPType = PTypeSpace.OBJLONG;
        } else if ("long".equals(sf.type())) {
          fieldType = Long.TYPE;
          fieldPType = PTypeSpace.LONG;
        } else {
          throw new PException(
              "Impossible to use an auto incremented identifier: " +
              "the field type of '" + sf.name + "' is '" + sf.type()
              + "' and 'java.lang.Long' or 'long' is expected (class '"
              + sc.getFQName() + "'.");
        }
                return new NamingField[] {
                    new NamingField(sf.name, fieldType, "lid", fieldPType)};
            }
        }
        return null;
    }
    public SpeedoColumn[] getDefaultColumn(SpeedoClass sc) {
        return new SpeedoColumn[] {new SpeedoColumn("lid")};
    }
   
}
TOP

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

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.