Package railo.runtime.type

Source Code of railo.runtime.type.QueryColumnImpl

package railo.runtime.type;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import railo.commons.lang.SizeOf;
import railo.runtime.PageContext;
import railo.runtime.config.NullSupportHelper;
import railo.runtime.dump.DumpData;
import railo.runtime.dump.DumpProperties;
import railo.runtime.dump.DumpUtil;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.exp.DatabaseException;
import railo.runtime.exp.DeprecatedException;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.exp.PageRuntimeException;
import railo.runtime.op.Caster;
import railo.runtime.op.Duplicator;
import railo.runtime.op.Operator;
import railo.runtime.op.ThreadLocalDuplication;
import railo.runtime.op.date.DateCaster;
import railo.runtime.reflection.Reflector;
import railo.runtime.reflection.pairs.MethodInstance;
import railo.runtime.type.dt.DateTime;
import railo.runtime.type.it.EntryIterator;
import railo.runtime.type.it.KeyIterator;
import railo.runtime.type.it.StringIterator;
import railo.runtime.type.scope.Undefined;
import railo.runtime.type.util.CollectionUtil;
import railo.runtime.type.util.QueryUtil;
import railo.runtime.util.ArrayIterator;

/**
* implementation of the query column
*/
public class QueryColumnImpl implements QueryColumnPro,Sizeable,Objects {

  private static final long serialVersionUID = -5544446523204021493L;
  private static final int CAPACITY=32;
   
  protected int type;
  protected int size;
  protected Object[] data;
   
    protected boolean typeChecked=false;
    protected QueryImpl query;
    protected Collection.Key key;

  /**
   * constructor with type
   * @param query
   * @param key
   * @param type
   */
    public QueryColumnImpl(QueryImpl query, Collection.Key key, int type) {
    this.data=new Object[CAPACITY];
    this.type=type;
        this.key=key;
        this.query=query;
  }

  /**
   * constructor with array
   * @param query
   * @param array
   * @param type
   */
    public QueryColumnImpl(QueryImpl query, Collection.Key key, Array array,int type) {
    data=array.toArray();
      size=array.size();
    this.type=type;
    this.query=query;
    this.key=key;
  }

  /**
   * @param query
   * @param type type as (java.sql.Types.XYZ) int
   * @param size
   */
    public QueryColumnImpl(QueryImpl query, Collection.Key key, int type, int size) {
    this.data=new Object[size];
    this.type=type;
    this.size=size;
    this.query=query;
    this.key=key;
  }
 

  /**
   * Constructor of the class
   * for internal usage only
   */
  public QueryColumnImpl() {
  }

  @Override
  public int size() {
    return size;
  }

  @Override
  public Collection.Key[] keys() {
    Collection.Key[] k=new Collection.Key[size()];
        int len=k.length;
    for(int i=1;i<=len;i++) {
      k[i-1]=KeyImpl.init(Caster.toString(i));
    }
    return k;
  }

  @Override
  public Object remove(Collection.Key key) throws PageException {
    resetType();
    return set(Caster.toIntValue(key.getString()),"");
  }

  @Override
  public Object remove(int row) throws DatabaseException {
        // query.disconnectCache();
        resetType();
    return set(row,"");
  }
 

  @Override
  public Object removeEL(Collection.Key key) {
        // query.disconnectCache();
        resetType();
    return setEL(Caster.toIntValue(key.getString(),-1),"");
  }

  @Override
  public Object removeEL(int row) {
        // query.disconnectCache();
        resetType();
    return setEL(row,"");
  }

  @Override
  public synchronized void clear() {
        // query.disconnectCache();
        resetType();
    data=new Object[CAPACITY];
    size=0;
  }
 
  @Override
  public Object remove(PageContext pc) throws PageException {
        return remove(query.getCurrentrow(pc.getId()));
  }

  public Object removeEL(PageContext pc) {
        return removeEL(query.getCurrentrow(pc.getId()));
  }
 
  @Override
  public Object get(String key) throws PageException {
        return get(KeyImpl.init(key));
  }
 
  @Override
  public Object get(Key key) throws PageException {
    return get((PageContext)null,key);
  }

  @Override
  public Object get(PageContext pc, Collection.Key key) throws PageException {
    int row=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
    if(row==Integer.MIN_VALUE) {
      Object child=getChildElement(pc,key,NullSupportHelper.NULL());
        if(child!=NullSupportHelper.NULL()) return child;
            throw new DatabaseException("key ["+key+"] not found",null,null,null);
        }
      return QueryUtil.getValue(this,row);
  }

    private Object getChildElement(PageContext pc,Key key, Object defaultValue) {// pc maybe null
      // column and query has same name
      if(key.equals(this.key)) {
          return query.get(key,defaultValue);
      }
      // get it from undefined scope
    pc = ThreadLocalPageContext.get(pc);
    if(pc!=null){
      Undefined undefined = pc.undefinedScope();
      boolean old = undefined.setAllowImplicidQueryCall(false);
      Object sister = undefined.get(this.key,NullSupportHelper.NULL());
      undefined.setAllowImplicidQueryCall(old);
      if(sister!=NullSupportHelper.NULL()){
        try {
          return pc.get(sister, key);
        } catch (PageException e) {
          return defaultValue;
        }
      }
    }
      return defaultValue;
  }

    /**
     * touch the given line on the column at given row
     * @param row
     * @return new row or existing
     * @throws DatabaseException
     */
    public Object touch(int row) {
      if(row<1 || row>size) return NullSupportHelper.full()?null:"";
        Object o=data[row-1];
        if(o!=null) return o;
        return setEL(row,new StructImpl());
    }
   
    /**
     * touch the given line on the column at given row
     * @param row
     * @return new row or existing
     * @throws DatabaseException
     */
    public Object touchEL(int row) {
      return touch(row);
    }
   
  @Override
  public Object get(Key key, Object defaultValue) {
    return get(null,key,defaultValue);
  }

  @Override
  public Object get(PageContext pc, Collection.Key key, Object defaultValue) {// pc maybe null
      int row=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
      if(row==Integer.MIN_VALUE) {
        return getChildElement(pc,key, defaultValue);
      }
      return get(row,defaultValue);
  }

  @Override
  public Object get(String key, Object defaultValue) {
      return get(KeyImpl.init(key),defaultValue);
  }

  @Override
    public Object get(int row) throws DeprecatedException {
    throw new DeprecatedException("this method is no longer supported, use instead get(int,Object)");
    //return QueryUtil.getValue(this,row);
    }

  @Override
    public Object get(int row, Object emptyValue) {
      if(row<1 || row>size) return emptyValue;
      return data[row-1]==null?emptyValue:data[row-1];
  }

  @Override
  public Object set(String key, Object value) throws PageException {
      int row=Caster.toIntValue(key,Integer.MIN_VALUE);
      if(row==Integer.MIN_VALUE)return query.set(key,value);
      return set(row,value);
  }

  public Object set(Collection.Key key, Object value) throws PageException {
      int row=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
      if(row==Integer.MIN_VALUE)return query.set(key,value);
      return set(row,value);
  }

    @Override
  public synchronized Object set(int row, Object value) throws DatabaseException {
        // query.disconnectCache();
        if(row<1) throw new DatabaseException("invalid row number ["+row+"]","valid row numbers a greater or equal to one",null,null);
      if(row>size) {
        if(size==0)throw new DatabaseException("cannot set a value to a empty query, you first have to add a row",null,null,null);
        throw new DatabaseException("invalid row number ["+row+"]","valid row numbers goes from 1 to "+size,null,null);
      }
     
      value=reDefineType(value);
      data[row-1]=value;
      return value;
  }
  @Override
  public synchronized Object setEL(String key, Object value) {
      int index=Caster.toIntValue(key,Integer.MIN_VALUE);
    if(index==Integer.MIN_VALUE) query.setEL(key,value);
      return setEL(index, value);
   
  }

  public Object setEL(Collection.Key key, Object value) {
      int index=Caster.toIntValue(key.getString(),Integer.MIN_VALUE);
    if(index==Integer.MIN_VALUE) query.setEL(key,value);
      return setEL(index, value);
  }

  @Override
  public synchronized Object setEL(int row, Object value) {
        // query.disconnectCache();
        if(row<1 || row>size) return value;
     
      value=reDefineType(value);
      data[row-1]=value;
      return value;
  }

    @Override
  public synchronized void add(Object value) {
        // query.disconnectCache();
        if(data.length<=size) growTo(size);
      data[size++]=value;
  }

    @Override
    public synchronized void cutRowsTo(int maxrows) {
        // query.disconnectCache();
        if(maxrows>-1 && maxrows<size)size=maxrows;
    }

  @Override
  public synchronized void addRow(int count) {     
        // query.disconnectCache();
        if(data.length<(size+count)) growTo(size+count);
      for(int i=0;i<count;i++)size++;
  }

    public synchronized Object removeRow(int row) throws DatabaseException {
        // query.disconnectCache();
        if(row<1 || row>size)
            throw new DatabaseException("invalid row number ["+row+"]","valid rows goes from 1 to "+size,null,null);
        Object o=data[row-1];
        for(int i=row;i<size;i++) {
            data[i-1]=data[i];
        }
        size--;
        if(NullSupportHelper.full()) return o;
        return o==null?"":o;
    }

  @Override
  public int getType() {
      reOrganizeType();
    return type;
  }
 
 
    @Override
  public String getTypeAsString() {
    return QueryImpl.getColumTypeName(getType());
  }


  @Override
  public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
    return DumpUtil.toDumpData(QueryUtil.getValue(this,query.getCurrentrow(pageContext.getId())), pageContext,maxlevel,dp);
 
 
    private synchronized void growTo(int row) {
       
        int newSize=(data.length+1)*2;
        while(newSize<=row) {
            //print.ln(newSize+"<="+row);
            newSize*=2;
        }
       
        Object[] newData=new Object[newSize];
        for(int i=0;i<data.length;i++) {
            newData[i]=data[i];
        }
        data=newData;
    }
   
    private Object reDefineType(Object value) {
        return QueryColumnUtil.reDefineType(this,value);
    }
   
    private synchronized void resetType() {
        QueryColumnUtil.resetType(this);
    }
   
    private synchronized void reOrganizeType() {
        QueryColumnUtil.reOrganizeType(this);
    }

    public Collection.Key getKey() {
        return key;
    }
    public void setKey(Collection.Key key) {
        this.key = key;
    }

  @Override
  public String getKeyAsString() throws PageException {
    return key.getLowerString();// TODO ist das OK?
  }

    @Override
    public Object get(PageContext pc) {
        return QueryUtil.getValue(this,query.getCurrentrow(pc.getId()));
    }
   
    @Override
    public Object get(PageContext pc, Object defaultValue) {
        return get(query.getCurrentrow(pc.getId()),defaultValue);
    }

    @Override
    public Object touch(PageContext pc) throws PageException {
        return touch(query.getCurrentrow(pc.getId()));
    }

    public Object touchEL(PageContext pc) {
        return touchEL(query.getCurrentrow(pc.getId()));
    }

    @Override
    public Object set(PageContext pc, Object value) throws PageException {
        return set(query.getCurrentrow(pc.getId()),value);
    }

    @Override
    public Object setEL(PageContext pc, Object value) {
        return setEL(query.getCurrentrow(pc.getId()),value);
    }

    @Override
    public Object getParent() {
        return query;
    }

    @Override
    public String castToString() throws PageException {
        return Caster.toString(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null));
    }

  @Override
  public String castToString(String defaultValue) {
    Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL());
    if(value==NullSupportHelper.NULL()) return defaultValue;
    return Caster.toString(value,defaultValue);
  }

    @Override
    public boolean castToBooleanValue() throws PageException {
        return Caster.toBooleanValue(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null));
    }
   
    @Override
    public Boolean castToBoolean(Boolean defaultValue) {
      Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL());
    if(value==NullSupportHelper.NULL()) return defaultValue;
    return Caster.toBoolean(value,defaultValue);
    }

    @Override
    public double castToDoubleValue() throws PageException {
        return Caster.toDoubleValue(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null));
    }
   
    @Override
    public double castToDoubleValue(double defaultValue) {
      Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL());
    if(value==NullSupportHelper.NULL()) return defaultValue;
    return Caster.toDoubleValue(value,defaultValue);
    }

    @Override
    public DateTime castToDateTime() throws PageException {
        return DateCaster.toDateAdvanced(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null),null);
    }
   
    @Override
    public DateTime castToDateTime(DateTime defaultValue) {
      Object value = get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),NullSupportHelper.NULL());
    if(value==NullSupportHelper.NULL()) return defaultValue;
    return DateCaster.toDateAdvanced(value,true,null,defaultValue);
    }


  @Override
  public int compareTo(boolean b) throws PageException {
    return Operator.compare(castToBooleanValue(), b);
  }

  @Override
  public int compareTo(DateTime dt) throws PageException {
    return Operator.compare((Date)castToDateTime(), (Date)dt);
  }

  @Override
  public int compareTo(double d) throws PageException {
    return Operator.compare(castToDoubleValue(), d);
  }

  @Override
  public int compareTo(String str) throws PageException {
    return Operator.compare(castToString(), str);
  }

    @Override
    public synchronized Object clone() {
        return duplicate(true);
    }

    public synchronized Collection duplicate(boolean deepCopy) {
        return cloneColumn(query,deepCopy);
    }
   
    public synchronized QueryColumnPro cloneColumn(Query query, boolean deepCopy) {
        return cloneColumnImpl(deepCopy);
    }
   
    public synchronized QueryColumnImpl cloneColumnImpl(boolean deepCopy) {
        QueryColumnImpl clone=new QueryColumnImpl();
        populate(this, clone, deepCopy);
        return clone;
    }
   
    protected static void populate(QueryColumnImpl src,QueryColumnImpl trg, boolean deepCopy) {
       
        ThreadLocalDuplication.set(src, trg);
        try{
          trg.key=src.key;
          trg.query=src.query;
          trg.size=src.size;
          trg.type=src.type;
          trg.key=src.key;
         
          trg.data=new Object[src.data.length];
          for(int i=0;i<src.data.length;i++) {
              trg.data[i]=deepCopy?Duplicator.duplicate(src.data[i],true):src.data[i];
          }
        }
        finally {
          // ThreadLocalDuplication.remove(src); removed "remove" to catch sisters and brothers
        }
    }
 

    @Override
    public String toString() {
        try {
            return Caster.toString(get(query.getCurrentrow(ThreadLocalPageContext.get().getId()),null));
        } catch (PageException e) {
            return super.toString();
        }
    }

    @Override
    public boolean containsKey(String key) {
        return containsKey(KeyImpl.init(key));
    }

  @Override
  public boolean containsKey(Collection.Key key) {
        return get(key,NullSupportHelper.NULL())!=NullSupportHelper.NULL();
  }

  @Override
  public long sizeOf() {
    return SizeOf.size(key)+SizeOf.size(data);
  }
 
  public Iterator iterator() {
    return keyIterator();
  }

  @Override
  public Iterator<Collection.Key> keyIterator() {
    return new KeyIterator(keys());
  }
   
  @Override
  public Iterator<String> keysAsStringIterator() {
      return new StringIterator(keys());
    }
 
  @Override
  public Iterator<Entry<Key, Object>> entryIterator() {
    return new EntryIterator(this, keys());
  }

  @Override
  public Iterator<Object> valueIterator() {
    return new ArrayIterator(data,0,size);
  }
 
  @Override
  public Object callWithNamedValues(PageContext pc, Key methodName,Struct args) throws PageException {
   
        throw new ExpressionException("No matching Method/Function ["+methodName+"] for call with named arguments found");
    //return pc.getFunctionWithNamedValues(get(query.getCurrentrow()), methodName, Caster.toFunctionValues(args));
  }

  @Override
  public Object call(PageContext pc, Key methodName, Object[] arguments) throws PageException {
    MethodInstance mi = Reflector.getMethodInstanceEL(this,this.getClass(), methodName, arguments);
    if(mi!=null) {
      try {
        return mi.invoke(this);
      } catch (Throwable t) {
        try {
          return pc.getFunction(QueryUtil.getValue(this,query.getCurrentrow(pc.getId())), methodName, arguments);
        } catch (PageException pe) {
          throw Caster.toPageException(t);
        }
      }
    }
    return pc.getFunction(QueryUtil.getValue(this,query.getCurrentrow(pc.getId())), methodName, arguments);
  }

  @Override
  public Object set(PageContext pc, Key propertyName, Object value) throws PageException {
    return set(propertyName, value);
  }

  @Override
  public Object setEL(PageContext pc, Key propertyName, Object value) {
    return setEL(propertyName, value);
  }

  public void add(int index, Object element) {
    throwNotAllowedToAlter();
    //setEL(index+1, element);
  }

  private void throwNotAllowedToAlter() {
    throw new PageRuntimeException(new DatabaseException(
        "Query columns do not support methods that would alter the structure of a query column"
        ,"you must use an analogous method on the query"
        ,null
        ,null));
   
  }

  public boolean addAll(java.util.Collection<? extends Object> c) {
    throwNotAllowedToAlter();
    return false;
    /*Iterator<? extends Object> it = c.iterator();
    while(it.hasNext()){
      add(it.next());
    }
    return true;*/
  }

  public boolean addAll(int index, java.util.Collection<? extends Object> c) {
    throwNotAllowedToAlter();
    return false;
    /*Iterator<? extends Object> it = c.iterator();
    while(it.hasNext()){
      setEL(++index,it.next());
    }
    return true;*/
  }

  public boolean contains(Object o) {
    return indexOf(o)!=-1;
  }

  public boolean containsAll(java.util.Collection<?> c) {
    Iterator<? extends Object> it = c.iterator();
    while(it.hasNext()){
      if(indexOf(it.next())==-1) return false;
    }
    return true;
  }

  public int indexOf(Object o) {
    for(int i=0;i<size;i++){
      try {
        if(Operator.compare(o, data[i])==0) return i;
      }
      catch (PageException e) {}
    }
    return -1;
  }

  public int lastIndexOf(Object o) {
    for(int i=size-1;i>=0;i--){
      try {
        if(Operator.compare(o, data[i])==0) return i;
      }
      catch (PageException e) {}
    }
    return -1;
  }

  public boolean isEmpty() {
    return size()==0;
  }

  public boolean removeAll(java.util.Collection<?> c) {
    throwNotAllowedToAlter();
    return false;
    /*boolean hasChanged=false;
    Iterator<? extends Object> it = c.iterator();
    while(it.hasNext()){
      if(remove(it.next())) {
        hasChanged=true;
      }
    }
    return hasChanged;*/
  }

  public boolean retainAll(java.util.Collection<?> c) {
    throwNotAllowedToAlter();
    return false;
    /*boolean hasChanged=false;
    Iterator it = valueIterator();
    while(it.hasNext()){
      if(!c.contains(it.next())){
        hasChanged=true;
        it.remove();
      }
    }
    return hasChanged;*/
  }

  public List<Object> subList(int fromIndex, int toIndex) {
    ArrayList<Object> list=new ArrayList<Object>();
    for(int i=fromIndex;i<toIndex;i++){
      list.add(data[i]);
    }
    return list;
  }

  public Object[] toArray() {
    return toArray(new Object[size()]);
  }

  public  Object[] toArray(Object[] trg) {
    System.arraycopy(data, 0, trg, 0, data.length>trg.length?trg.length:data.length);
    return trg;
  }

  @Override
  public QueryColumnPro toDebugColumn() {
    return _toDebugColumn();
  }
 
  public DebugQueryColumn _toDebugColumn() {
    return new DebugQueryColumn(data,key,query,size,type,typeChecked);
  }
 
  @Override
  public java.util.Iterator<String> getIterator() {
      return keysAsStringIterator();
    }
 
  @Override
  public boolean equals(Object obj){
    if(!(obj instanceof Collection)) return false;
    return CollectionUtil.equals(this,(Collection)obj);
  }

  @Override
  public int getDimension() {
    return 1;
  }

  @Override
  public Object getE(int row) throws PageException {
    return get(row);
  }

  @Override
  public Object setE(int key, Object value) throws PageException {
    return set(key, value);
  }

  @Override
  public int[] intKeys() {
    int[] keys=new int[size()];
        int len=keys.length;
    for(int i=1;i<=len;i++) {
      keys[i-1]=i;
    }
    return keys;
  }

  @Override
  public boolean insert(int key, Object value) throws PageException {
    throwNotAllowedToAlter();
    return false;
  }

  @Override
  public Object append(Object o) throws PageException {
    throwNotAllowedToAlter();
    return o;
  }

  @Override
  public Object appendEL(Object o) {
    throwNotAllowedToAlter();
    return o;
  }

  @Override
  public Object prepend(Object o) throws PageException {
    throwNotAllowedToAlter();
    return o;
  }

  @Override
  public void resize(int to) throws PageException {
    throwNotAllowedToAlter();
  }

  @Override
  public void sort(String sortType, String sortOrder) throws PageException {
    throwNotAllowedToAlter();
  }

  @Override
  public void sort(Comparator comp) throws PageException {
    throwNotAllowedToAlter();
  }

  @Override
  public List toList() {
    Iterator<Object> it = valueIterator();
    ArrayList list=new ArrayList();
        while(it.hasNext()){
          list.add(it.next());
        }
        return list;
  }

  @Override
  public Object removeE(int key) throws PageException {
    throwNotAllowedToAlter();
    return null;
  }

  @Override
  public boolean containsKey(int key) {
    return get(key,NullSupportHelper.NULL())!=NullSupportHelper.NULL();
  }
 
  /*@Override
  public int hashCode() {
    return CollectionUtil.hashCode(this);
  }*/
}
TOP

Related Classes of railo.runtime.type.QueryColumnImpl

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.