Package org.objectweb.speedo.naming.lib

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

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

import org.objectweb.asm.Type;
import org.objectweb.jorm.api.PException;
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.naming.api.PName;
import org.objectweb.jorm.naming.api.PNameCoder;
import org.objectweb.jorm.type.api.PType;
import org.objectweb.medor.filter.lib.ExpressionPrinter;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.api.SpeedoRuntimeException;
import org.objectweb.speedo.generation.enhancer.pc.POVariableNames;
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.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.naming.api.UserId;
import org.objectweb.speedo.naming.api.UserIdFactory;
import org.objectweb.util.monolog.api.BasicLevel;


/**
*
* @author S.Chassande-Barrioz
*/
public class UserIdCompositeNamingManager
  extends NamingManagerHelper
  implements NamingManager {

  private final static String COMPOSITE_USER_ID = "cuid";

  protected String getName() {
    return COMPOSITE_USER_ID;
  }

    // IMPLEMENTATION OF THE METHOD FROM THE NamingManager INTERFACE //
    //---------------------------------------------------------------//
    public boolean canManage(SpeedoClass sc) {
        if (sc.identity.strategy == SpeedoIdentity.USER_ID) {
            String objectidClass = sc.identity.objectidClass;
            if (objectidClass == null && sc.generateObjectId()) {
                objectidClass = NamingRules.generatedObjectIdName(sc.getFQName());
            }
            return objectidClass != null;
        }
        return false;
    }
    public Object encode(PName pn) throws PException {
        if (pn instanceof UserIdFactory) {
            return ((UserIdFactory) pn).getNewUserId();
        }
        return null;
    }
    public PName decode(PNameCoder pnc,
                        Object oid,
                        java.lang.Class clazz,
                        JormFactory jf) throws PException {
        if (oid instanceof UserId) {
            //the oid is a UserId
            if (pnc != null) {
                //Use the pnc found by the clazz
                return pnc.decodeAbstract(oid, null);
            } else if (((UserId) oid).speedoGetPersistentClassName() != null) {
                //No pnc but the class name is inside the UserId
                ClassLoader cl = oid.getClass().getClassLoader();
                if (cl == null) {
                    cl = jf.getClass().getClassLoader();
                }
                if (cl == null) {
                    cl = ClassLoader.getSystemClassLoader();
                }
                return jf.getPNamingContext(
                        ((UserId) oid).speedoGetPersistentClassName(), cl)
                        .decodeAbstract(oid, null);
            }
        } else if (pnc != null
                && (oid instanceof String)
                && (pnc.getNull() instanceof UserIdFactory)) {
            //The oid is a String which must be the parameter of the constructor
            java.lang.Class idclass = ((UserIdFactory) pnc.getNull())
                    .getNewUserId().getClass();
            Object o = null;
            try {
                o = idclass.getConstructor(new java.lang.Class[]{String.class})
                        .newInstance(new Object[]{(String) oid});
            } catch (Exception e) {
                throw new SpeedoRuntimeException("No constructor with a String " +
                        "parameter available on the identifier class: "
                        + idclass.getName());
            }
            //recall with the UserId
            return decode(pnc, o, clazz, jf);
        }

        return null;
    }
    public boolean canProvidePBinder(Object hints, ClassLoader classLoader) {
    if(!super.canProvidePBinder(hints, classLoader)) {
      return false;
    }
    String cn = getBinderClassNameFromHints(hints, COMPOSITE_USER_ID);
    if (cn == null) {
      return false;
    }
        try {
            classLoader.loadClass(cn);
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }
    }
    public boolean canProvidePNamingContext(Object hints, ClassLoader classLoader) {
    if(!super.canProvidePNamingContext(hints, classLoader)) {
      return false;
    }
    String cn = getPNCClassNameFromHints(hints, COMPOSITE_USER_ID);
    if (cn == null) {
      return false;
    }
    try {
      classLoader.loadClass(getPNCClassNameFromHints(hints, COMPOSITE_USER_ID));
      return true;
    } catch (ClassNotFoundException e) {
      return false;
    }
    }
    public void defineClassIdentifierNameDef(NameDef nd,
            Class jc,
            SpeedoClass sc,
            ClassMapping cm,
            MIBuilderHelper mibh,
            JormMIMappingBuilder mb,
            Collection createdMOs) throws SpeedoException, PException {
    boolean debug = logger.isLoggable(BasicLevel.DEBUG);
    if (debug) {
      logger.log(BasicLevel.DEBUG,
              "CompositeUserId: Filling the identifider name def: \n\t class="
              + sc.getFQName());
    }
    SpeedoClass clazzWithIdField = sc.getAncestor();
    if (clazzWithIdField == null) {
        clazzWithIdField = sc;
    }
        List idFields = clazzWithIdField.getPKFields();
        String objectidClass = clazzWithIdField.identity.objectidClass;
        if (objectidClass == null && sc.generateObjectId()) {
            objectidClass = NamingRules.generatedObjectIdName(clazzWithIdField.getFQName());
            clazzWithIdField.identity.oidClassAutoCalculated = true;
            clazzWithIdField.identity.objectidClass = objectidClass;
        }
        Manager manager = (Manager) jc.getPackage().getParent();
        //The user has specified an object id ==> use it for the namedef
        CompositeName cn = manager.getCompositeName(objectidClass);
        boolean cnNotDefined = (cn == null);
        if (cnNotDefined) {
      if (debug) {
        logger.log(BasicLevel.DEBUG, "\tCreate the composite name " + objectidClass);
      }
            cn = manager.createCompositeName(objectidClass);
            createdMOs.add(cn);
        }
        NameRef nr = nd.createNameRef(cn);
        for (int i = 0; i < idFields.size(); i++) {
            SpeedoField pkField = (SpeedoField) idFields.get(i);
            int size = PType.NOSIZE;
            int scale = PType.NOSIZE;
            if (pkField.columns != null && pkField.columns.length == 1) {
                if (pkField.columns[0].length != -1) {
                    size = pkField.columns[0].length;
                }
                if (pkField.columns[0].scale!= -1) {
                    scale = pkField.columns[0].scale;
                }
            }
            if (cnNotDefined) {
                cn.createCompositeNameField(pkField.name,
                        mibh.getPrimitivePType(Type.getType(pkField.type)),
                        size, scale);
            }
            nr.addProjection(pkField.name, pkField.name);
        }
    }
    public boolean needInheritanceDiscriminator(SpeedoClass sc)
      throws SpeedoException {
        return true;
    }

    /**
     * This internal method defines a NameDef based on on the PK fields of the
     * Referenced class. This method manages ClassRef owned by a class or by
     * a generic class. But this method does not mapped the fields (ex:
     * no rdb mapping)
     * @param nd is the namedef to fill
     * @param cr is the JORM meta object representing the reference.  This
     * ClassRef can be owned by a Class or a GenClassRef.
     * @param sf is the Speedo MetaObject representing the persistent field
     * linked to this ClassRef. If the owner of the ClassRef is a simple class
     * then this parameter represents the classRef too. If the owner of the
     * ClassRef is a generic class, then this parameter represents the reference
     * to the generic class (Collection, Map, ...).
     * @param mibh is a helper for the management of the JORM meta info
     * @param prefix is a prefix for the name of the field composing the
     * identifier
     */
    private void defineClassReferenceNameDef(NameDef nd,
            ClassRef cr,
            SpeedoField sf,
            MIBuilderHelper mibh,
            String prefix) throws SpeedoException, PException {
        Manager manager = mibh.getManager(cr);
        SpeedoClass referencedClass = sf.moClass.getSpeedoClassFromContext(
                cr.getMOClass().getFQName());
    SpeedoClass clazzWithIdField = referencedClass.getAncestor();
    if (clazzWithIdField == null) {
        clazzWithIdField = referencedClass;
    }
        CompositeName cn = manager.getCompositeName(clazzWithIdField.identity.objectidClass);
        NameRef nr = nd.createNameRef(cn);
        List idFields = clazzWithIdField.getPKFields();
        for (int i = 0; i < idFields.size(); i++) {
            SpeedoField pkField = (SpeedoField) idFields.get(i);
            int size = PType.NOSIZE;
            int scale = PType.NOSIZE;
            if (pkField.columns != null && pkField.columns.length == 1) {
                if (pkField.columns[0].length != -1) {
                    size = pkField.columns[0].length;
                }
                if (pkField.columns[0].scale != -1) {
                    scale = pkField.columns[0].scale;
                }
            }
      // create a hidden field in the class corresponding to this
      // composite Name field. The name is based on a prefix (ClassRef name)
            String fieldName = prefix + pkField.name;
            PType type = mibh.getPrimitivePType(Type.getType(pkField.type));
      if (logger.isLoggable(BasicLevel.DEBUG)) {
        logger.log(BasicLevel.DEBUG, "\tField: name=" + fieldName
                + ", type=" + type.getJavaName());
      }
            mibh.createNameDefField(cr.getParent(), fieldName, type, size, scale);
            //define the projection between composite name fields and field used
            // in NameRef
            nr.addProjection(pkField.name, fieldName);
        }
    }
    public void defineClassReferenceNameDef(NameDef nd,
            ClassRef cr,
            SpeedoField sf,
            SpeedoClass currentClass,
            ClassMapping cm,
            MIBuilderHelper mibh,
            JormMIMappingBuilder mb) throws SpeedoException, PException {
    if (logger.isLoggable(BasicLevel.DEBUG)) {
      logger.log(BasicLevel.DEBUG, "CompositeUserId: Filling the name def of a ClassRef from a class: "
        + "\n\tField: " + currentClass.getFQName() + "#" + sf.name
        + "\n\ttarget class=" + sf.getClassName());
    }
        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 {
    if (logger.isLoggable(BasicLevel.DEBUG)) {
      logger.log(BasicLevel.DEBUG, "CompositeUserId: Filling the name def of a ClassRef from a class: "
        + "\n\tField: " + currentClass.getFQName() + "#" + sf.name
        + "\n\ttarget class=" + sf.getClassName());
    }
        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 {
        String prefix = mibh.getNameDefFieldPrefix(gcr, isGCId, isGCId, sf);
        Manager manager = mibh.getManager(gcr);
    SpeedoClass clazzWithIdField = sf.moClass.getAncestor();
    if (clazzWithIdField == null) {
        clazzWithIdField = sf.moClass;
    }
        CompositeName cn = manager.getCompositeName(clazzWithIdField.identity.objectidClass);
        NameRef nr = nd.createNameRef(cn);
        List idFields = clazzWithIdField.getPKFields();
        for (int i = 0; i < idFields.size(); i++) {
            SpeedoField pkField = (SpeedoField) idFields.get(i);
      // create a hidden field in the class corresponding to this
      // composite Name field. The name is based on a prefix (GenClassRef name)
            String fieldName = prefix + pkField.name;
      if (logger.isLoggable(BasicLevel.DEBUG)) {
        logger.log(BasicLevel.DEBUG, "\tField: name=" + fieldName);
      }
            if (isGCId) {
                PType type = mibh.getPrimitivePType(Type.getType(pkField.type));
                int size = PType.NOSIZE;
                int scale = PType.NOSIZE;
                if (pkField.columns != null && pkField.columns.length == 1) {
                    if (pkField.columns[0].length != -1) {
                        size = pkField.columns[0].length;
                    }
                    if (pkField.columns[0].scale != -1) {
                        scale = pkField.columns[0].scale;
                    }
                }
                mibh.createNameDefField(gcr, fieldName, type, size, scale);
            }
            //define the projection between composite name fields and field used
            // in NameRef
            nr.addProjection(pkField.name, fieldName);
        }
    }
    public void defineGenClassIdentifierNameDef(NameDef nd,
            GenClassRef gcr,
            SpeedoField sf,
            SpeedoClass currentClass,
            GenClassMapping gcm,
            MIBuilderHelper mibh,
            JormMIMappingBuilder mb) throws SpeedoException, PException {
    if (logger.isLoggable(BasicLevel.DEBUG)) {
      logger.log(BasicLevel.DEBUG, "CompositeUserId: Filling the name def identifier of a GenClassRef: "
        + "\n\tField: " + currentClass.getFQName() + "#" + sf.name);
    }
    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 {
    if (logger.isLoggable(BasicLevel.DEBUG)) {
      logger.log(BasicLevel.DEBUG, "CompositeUserId: Filling the name def of a GenClassRef: "
        + "\n\tField: " + currentClass.getFQName() + "#" + sf.name);
    }
    defineGenClassNameDef(nd, gcr, sf, mibh, false);
    }
   
    public String getPNameHints(SpeedoClass sc, NameDef nd) {
        return "this." + POVariableNames.REFSTATE_FIELD_NAME;
    }
    public Object[] getPNameHints2(SpeedoClass sc, NameDef nd) {
        return new Object[]{PNH_REF_STATE};
    }

  public String getGCPNameHints(SpeedoClass sc, NameDef nd) {
    return "speedoPO.getPName()";
  }

  /**
   * Build a property value compsed such as this pattern
   * userid,binder_class_name,pnc_class_name,class_name
   * @param nd
   * @param targetClass
   * @param sourceMO
   * @param key
   * @param result
   */
  public void getJormNamingConfig(NameDef nd,
                  SpeedoClass targetClass,
                  MetaObject sourceMO,
                  String key,
                  Properties result) throws SpeedoException {
    StringBuffer sb = new StringBuffer();
    sb.append(COMPOSITE_USER_ID);
    sb.append(HINTS_SEP);
    String binderClassName = NamingRules.binderName(
      nd.getNameRef().getCompositeName().getFQName());
    sb.append(binderClassName);
    sb.append(HINTS_SEP);
    String className = targetClass.getFQName();
    SpeedoClass ancestor = targetClass.getAncestor();
    if (sourceMO instanceof GenClassRef //For a Genclass ref or identifier
      || (ancestor == null //No inheritance
        && targetClass.jormclass.getSubClasses().isEmpty())) {
      sb.append(binderClassName);
    } else {
      if (ancestor == null) {
        ancestor = targetClass;
      }
      try {
        logger.log(BasicLevel.DEBUG, "Class " + targetClass.jormclass.getFQName() + "\n"
                    + "  NamedDef " + nd.toString() + "\n"
                    + "  Filter " + ExpressionPrinter.e2str(targetClass.jormclass.getInheritanceFilter(nd)) );
        if (targetClass.jormclass.getSubClasses().isEmpty()) {
          sb.append(binderClassName);
        } 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
          logger.log(BasicLevel.DEBUG, "Composite PName : assign a polymorphic PNC for the class" + targetClass.jormclass.getFQName() + ".");
          sb.append(POLYMORPHIC_PNC);
        } else {
          //use a kfpnc
          logger.log(BasicLevel.DEBUG, "Composite PName : assign a KFPNC for the class" + targetClass.jormclass.getFQName() + ".");
          sb.append(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);
      }
      className = ancestor.getFQName();
    }
    sb.append(HINTS_SEP);
    sb.append(className);
    result.setProperty(key, sb.toString());
    }

}
TOP

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

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.