Package org.objectweb.speedo.genclass.collection

Source Code of org.objectweb.speedo.genclass.collection.CollectionElem

/**
* 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.genclass.collection;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;

import javax.jdo.PersistenceManager;

import org.objectweb.jorm.api.PException;
import org.objectweb.jorm.api.PIndexedElem;
import org.objectweb.jorm.naming.api.PName;
import org.objectweb.jorm.naming.api.PNamingContext;
import org.objectweb.jorm.type.api.PExceptionTyping;
import org.objectweb.speedo.genclass.GenClassAccessor;
import org.objectweb.speedo.genclass.GenClassElement;
import org.objectweb.speedo.mim.api.StateItf;
import org.objectweb.speedo.mim.api.PersistentObjectItf;
import org.objectweb.speedo.pm.api.POManagerItf;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.api.Logger;

/**
* @author  P. D?chamboux
*/
public class CollectionElem implements PIndexedElem, GenClassElement {

  public final static boolean ELEMENT_IS_PNAME = true;
 
    /**
     * The error message thrown when an accessor method associated to a
     * primitive element type is called. Indeed this implementation supports
     * only object elements.
     */
    public final static String ERROR_MESSAGE_BAD_FIELD_NAME =
            "Wrong index field name";

    /**
     * The error message thrown when an accessor method associated to a
     * primitive element type is called. Indeed this implementation supports
     * only object elements.
     */
    public final static String ERROR_MESSAGE_NO_NULL_INDEX =
            "Null value not supported for index field";

    /**
     * This constant is the name of the index field. This value must be use with
     * the methods associated to the management of the index.
     */
    public final static String INDEX_FIELD_NAME = "idx";

    /**
     * This field is the element (or its PName for a reference).
     */
    protected Object element;

    /**
     * This field can be the index. The index type is known at instanciation
     * time.
     */
    protected Object index;

    /**
     * This field represents the satus of the PIndexedEleme. The possible value
     * are ELEM_CREATED, ELEM_DELETED, ELEM_MODIFIED, ELEM_UNMODIFIED
     */
    protected byte status = ELEM_CREATED;

    protected GenClassAccessor gca;

    public CollectionElem(GenClassAccessor gca) {
        this.gca = gca;
    }

   
    public GenClassElement cloneGCE() {
        return cloneGCE(new CollectionElem(gca));
    }
   
    public GenClassElement cloneGCE(GenClassElement gce) {
        ((CollectionElem) gce).status = status;
        ((CollectionElem) gce).element = element;
        ((CollectionElem) gce).index = index;
        return gce;
    }
   
    // IMPLEMENTATION OF THE GenClassElement INTERFACE //
    // ------------------------------------------------//

    public Object getIndex() {
        return index;
    }

    public void setIndex(Object index) {
        this.index = index;
    }

    /**
     * @return the element of the gen class. It is a user object.
     */
    public synchronized Object getElement() {
    return getElement(null);
    }

    /**
     * Assignes the element of the gen class. It is a user object.
     * @param element to add
     */
    public void setElement(Object element) {
        this.element = element;
    }

    /**
     * @param pm is the persistence manager which permits to resolve the PName
     * into a java reference.
     * @return the element of the gen class. The element is a reference
     * (PersistentObjectItf).
     */
    public Object getElement(POManagerItf pm) {
    Object res = element;
        if (res instanceof PName) {
      synchronized(this) {
        if (res instanceof PName) {
                    POManagerItf mypm = pm;
          if (mypm == null) {
                        mypm = ((PersistentObjectItf) gca.gcpo).speedoGetPOManager();
          }
                res = mypm.speedoGetObject((PName) res, false);
        }
        if (status != PIndexedElem.ELEM_DELETED) {
            //when an element is deleted, it will be unbound from its
            // identifier. Then all futur GenClassElement comparaison
            // will be impossible if we do not have the identifier 
          element = res;
        }
      }
        }
        return res;
    }

    public StateItf getSpeedoAccessor() {
        return gca;
    }

  public void unSwizzle() {
    if (element instanceof PersistentObjectItf) {
      synchronized(this) {
        if (element instanceof PersistentObjectItf) {
          element = ((PersistentObjectItf) element).getPName();
        }
      }
    }
  }

  byte statusForMerge = PIndexedElem.ELEM_UNMODIFIED;
 
    public void cleanStatusForMerge() {
        statusForMerge = PIndexedElem.ELEM_UNMODIFIED;
    }
    public byte getStatusForMerge() {
        return statusForMerge;
    }
    public byte retainStatusForMerge() {
        statusForMerge = status;
        return statusForMerge;
    }
   
    //  IMPLEMENTATION OF THE Serializable INTERFACE //
    // ---------------------------------------------//

    /**
     * If the element is a PName, do not serialize it.
     * Else, serialize it.
     */
    private void writeObject(ObjectOutputStream out) throws IOException {
      if (!(element instanceof PName)) {
        out.writeBoolean(!ELEMENT_IS_PNAME);
        out.writeObject(element);
      } else {
        out.writeBoolean(ELEMENT_IS_PNAME);
      }
      out.writeObject(gca);
      out.writeObject(index);
      out.writeByte(status);
      out.writeByte(statusForMerge);
    }
   
    /**
     * Symmetric method to de-serialize the object: test on if the element has been
     * serialized or not.
     */
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
      //if the element attribute has been serialized, read it
      if (in.readBoolean() != ELEMENT_IS_PNAME)
        element = in.readObject();
      else
        element = null;
      gca = (GenClassAccessor) in.readObject();
      index = in.readObject();
      status = in.readByte();
      statusForMerge = in.readByte();
    }
   
    // IMPLEMENTATION OF THE PIndexedElem INTERFACE //
    // ---------------------------------------------//

    public byte getElemStatus() {
        return status;
    }

    public String pieGetStringElem() throws PExceptionTyping {
        return (String) element;
    }

    public Date pieGetDateElem() throws PExceptionTyping {
        return (Date) element;
    }

    public char[] pieGetCharArrayElem() throws PExceptionTyping {
        return (char[]) element;
    }

    public byte[] pieGetByteArrayElem() throws PExceptionTyping {
        return (byte[]) element;
    }

    public Serializable pieGetSerializedElem() throws PExceptionTyping {
        return (Serializable) element;
    }

    public PName pieGetRefElem() {
        PName pn = (PName) (element instanceof PersistentObjectItf
            ? ((PersistentObjectItf) element).getPName()
            : element);
        try {
            pn = ((PNamingContext) gca.getSpeedoPO().getPClassMapping()
                    .getPNameCoder()).export(null, pn);
        } catch (Exception e) {
        }
        return pn;
    }

    public boolean pieGetBooleanElem() throws PExceptionTyping {
        return ((Boolean) element).booleanValue();
    }

    public Boolean pieGetObooleanElem() throws PExceptionTyping {
        return (Boolean) element;
    }

    public byte pieGetByteElem() throws PExceptionTyping {
        return ((Byte) element).byteValue();
    }

    public Byte pieGetObyteElem() throws PExceptionTyping {
        return (Byte) element;
    }

    public char pieGetCharElem() throws PExceptionTyping {
        return ((Character) element).charValue();
    }

    public Character pieGetOcharElem() throws PExceptionTyping {
        return (Character) element;
    }

    public short pieGetShortElem() throws PExceptionTyping {
        return ((Short) element).shortValue();
    }

    public Short pieGetOshortElem() throws PExceptionTyping {
        return (Short) element;
    }

    public int pieGetIntElem() throws PExceptionTyping {
        return ((Integer) element).intValue();
    }

    public Integer pieGetOintElem() throws PExceptionTyping {
        return (Integer) element;
    }

    public long pieGetLongElem() throws PExceptionTyping {
        return ((Long) element).longValue();
    }

    public Long pieGetOlongElem() throws PExceptionTyping {
        return (Long) element;
    }

    public float pieGetFloatElem() throws PExceptionTyping {
        return ((Float) element).floatValue();
    }

    public Float pieGetOfloatElem() throws PExceptionTyping {
        return (Float) element;
    }

    public double pieGetDoubleElem() throws PExceptionTyping {
        return ((Double) element).doubleValue();
    }

    public Double pieGetOdoubleElem() throws PExceptionTyping {
        return (Double) element;
    }

    public BigDecimal pieGetBigDecimalElem() throws PException {
        return (BigDecimal) element;
    }

  public BigInteger pieGetBigIntegerElem() throws PException {
    return (BigInteger) element;
  }

    public void pieSetStringElem(String value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetDateElem(Date value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetCharArrayElem(char[] value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetByteArrayElem(byte[] value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetSerializedElem(Serializable value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetRefElem(PName value) throws PExceptionTyping {
        element = value;
        /*
        try {
          PersistenceManager pm = gca.speedoPO.jdoGetPersistenceManager();
          JDOTransactionItf tx = (JDOTransactionItf) pm.currentTransaction();
            element = value.resolve(tx.getConnectionHolder());
        } catch (Exception e) {
            ExceptionHelper.getNested(e).printStackTrace();
            element = value;
        }
        */
    }

    public void pieSetBooleanElem(boolean value) throws PExceptionTyping {
        element = Boolean.valueOf(value);
    }

    public void pieSetObooleanElem(Boolean value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetByteElem(byte value) throws PExceptionTyping {
        element = new Byte(value);
    }

    public void pieSetObyteElem(Byte value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetCharElem(char value) throws PExceptionTyping {
        element = new Character(value);
    }

    public void pieSetOcharElem(Character value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetShortElem(short value) throws PExceptionTyping {
        element = new Short(value);
    }

    public void pieSetOshortElem(Short value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetIntElem(int value) throws PExceptionTyping {
        element = new Integer(value);
    }

    public void pieSetOintElem(Integer value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetLongElem(long value) throws PExceptionTyping {
        element = new Long(value);
    }

    public void pieSetOlongElem(Long value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetFloatElem(float value) throws PExceptionTyping {
        element = new Float(value);
    }

    public void pieSetOfloatElem(Float value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetDoubleElem(double value) throws PExceptionTyping {
        element = new Double(value);
    }

    public void pieSetOdoubleElem(Double value) throws PExceptionTyping {
        element = value;
    }

    public void pieSetBigDecimalElem(BigDecimal bigDecimal) throws PException {
        element = bigDecimal;
    }

  public void pieSetBigIntegerElem(BigInteger value) throws PException {
    element = value;
  }
    // ---------------------------------------------------------------------------
    // Index accessor
    // ---------------------------------------------------------------------------

    public void pieSetByteIndexField(String fn, byte value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        index = new Byte(value);
    }

    public void pieSetObyteIndexField(String fn, Byte value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        if (value == null)
            throw new PExceptionTyping(ERROR_MESSAGE_NO_NULL_INDEX);
        index = value;
    }

    public void pieSetCharIndexField(String fn, char value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        index = new Character(value);
    }

    public void pieSetOcharIndexField(String fn, Character value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        if (value == null)
            throw new PExceptionTyping(ERROR_MESSAGE_NO_NULL_INDEX);
        index = value;
    }

    public void pieSetShortIndexField(String fn, short value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        index = new Short(value);
    }

    public void pieSetOshortIndexField(String fn, Short value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        if (value == null)
            throw new PExceptionTyping(ERROR_MESSAGE_NO_NULL_INDEX);
        index = value;
    }

    public void pieSetIntIndexField(String fn, int value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        index = new Integer(value);
    }

    public void pieSetOintIndexField(String fn, Integer value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        if (value == null)
            throw new PExceptionTyping(ERROR_MESSAGE_NO_NULL_INDEX);
        index = value;
    }

    public void pieSetLongIndexField(String fn, long value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        index = new Long(value);
    }

    public void pieSetOlongIndexField(String fn, Long value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        if (value == null)
            throw new PExceptionTyping(ERROR_MESSAGE_NO_NULL_INDEX);
        index = value;
    }

    public void pieSetStringIndexField(String fn, String value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        if (value == null)
            throw new PExceptionTyping(ERROR_MESSAGE_NO_NULL_INDEX);
        index = value;
    }

    public void pieSetDateIndexField(String fn, Date value) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        if (value == null)
            throw new PExceptionTyping(ERROR_MESSAGE_NO_NULL_INDEX);
        index = value;
    }

    public short pieGetShortIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return ((Short) index).shortValue();
    }

    public Short pieGetOshortIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return (Short) index;
    }

    public long pieGetLongIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return ((Long) index).longValue();
    }

    public Long pieGetOlongIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return (Long) index;
    }

    public int pieGetIntIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return ((Integer) index).intValue();
    }

    public Integer pieGetOintIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return (Integer) index;
    }

    public String pieGetStringIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return (String) index;
    }

    public Date pieGetDateIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return (Date) index;
    }

    public byte pieGetByteIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return ((Byte) index).byteValue();
    }

    public Byte pieGetObyteIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return (Byte) index;
    }

    public char pieGetCharIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return ((Character) index).charValue();
    }

    public Character pieGetOcharIndexField(String fn) throws PExceptionTyping {
        if (!INDEX_FIELD_NAME.equals(fn))
            throw new PExceptionTyping(ERROR_MESSAGE_BAD_FIELD_NAME);
        return (Character) index;
    }

    // ---------------------------------------------------------------------------
    // Other methods
    // ---------------------------------------------------------------------------

    public void setStatus(byte s) {
        status = s;
        if (status == PIndexedElem.ELEM_DELETED) {
            //One of the reason to remove an element from the collection, is
            //that the element is deleted. So when the element is deleted, it
            // is not no more bound to a PName. Then here we decide to fetch the
            // PName in advance but when it is possible.
            unSwizzle();
        }
    }

    public boolean equals(Object o) {
    if (!(o instanceof CollectionElem)) {
      return false;
    }
    Object objIndex = ((CollectionElem) o).getIndex();
    if ((index == null && objIndex != null) ||
            (index != null && !index.equals(objIndex))) {
        return false;
    }
    //Store the element value in a local variable in order to avoid
    // syncrhonization
    Object objElement = element;
    //Fetch the real element without causing the loading of the persistent
    //instance: do not use the getElement() methods, but direct access to
    // the field.
    Object ceElem =  ((CollectionElem) o).element;
    if (objElement == null) {
      return ceElem == null;
    }
    if (ceElem == null) {
      return false;
    }
    if (objElement instanceof PName) {
      if (ceElem instanceof PName) {
        return objElement.equals(ceElem);
      } else if (ceElem instanceof PersistentObjectItf) {
        return objElement.equals(((PersistentObjectItf) ceElem).getPName());
      } else {
        return false;
      }
    } else if (objElement instanceof PersistentObjectItf) {
      if (ceElem instanceof PName) {
          Object pn = ((PersistentObjectItf) objElement).getPName();
          if (pn == null) {
              Logger l = gca.getLogger();
              if (l != null) {
                  l.log(BasicLevel.WARN,
                          "Internal error: a collection/set/map elemnent is no more persistent and it is impossible to compare it: ",
                          new RuntimeException());
              }
              return false;
          } else {
              return pn.equals(ceElem);
          }
      } else if (ceElem instanceof PersistentObjectItf) {
        return objElement == ceElem;
      } else {
        return false;
      }
    } else {
      return  objElement.equals(ceElem);
    }
    }
}
TOP

Related Classes of org.objectweb.speedo.genclass.collection.CollectionElem

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.