All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.gs.fw.common.mithra.finder.LinkedMapper Maven / Gradle / Ivy

There is a newer version: 18.1.0
Show newest version
/*
 Copyright 2016 Goldman Sachs.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing,
 software distributed under the License is distributed on an
 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 KIND, either express or implied.  See the License for the
 specific language governing permissions and limitations
 under the License.
 */

package com.gs.fw.common.mithra.finder;

import com.gs.collections.api.block.function.Function;
import com.gs.collections.impl.list.mutable.FastList;
import com.gs.fw.common.mithra.MithraList;
import com.gs.fw.common.mithra.MithraObjectPortal;
import com.gs.fw.common.mithra.attribute.AsOfAttribute;
import com.gs.fw.common.mithra.attribute.Attribute;
import com.gs.fw.common.mithra.cache.ConcurrentFullUniqueIndex;
import com.gs.fw.common.mithra.extractor.Extractor;
import com.gs.fw.common.mithra.finder.asofop.AsOfEqOperation;
import com.gs.fw.common.mithra.notification.MithraDatabaseIdentifierExtractor;
import com.gs.fw.common.mithra.util.HashUtil;
import com.gs.fw.common.mithra.util.InternalList;
import com.gs.fw.common.mithra.util.ListFactory;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.*;



public class LinkedMapper implements Mapper, Externalizable
{

    private List mappers;
    private boolean isToMany = false;

    public LinkedMapper()
    {
        // for externalizable
        this.mappers = new FastList(4);
    }

    public LinkedMapper(Mapper first, Mapper second)
    {
        this.mappers = new FastList(4);
        this.addMapper(first);
        this.addMapper(second);
    }

    private LinkedMapper(List mappers)
    {
        this.mappers = mappers;
    }

    public void setAnonymous(boolean anonymous)
    {
        throw new RuntimeException("should never get here");
    }

    public boolean isAnonymous()
    {
        return false;
    }

    public void setToMany(boolean toMany)
    {
        isToMany = toMany;
    }

    public boolean isToMany()
    {
        return isToMany;
    }

    public String getRelationshipPath()
    {
        StringBuffer buf = new StringBuffer();
        for(Mapper mapper : this.mappers)
        {
            if (mapper instanceof AbstractMapper)
            {
                AbstractMapper aMapper = (AbstractMapper) mapper;
                buf.append(aMapper.getRawName() + ".");
            }
        }
        if (buf.length() > 1)
        {
            buf.deleteCharAt(buf.length()-1);
        }
        return buf.toString();
    }

    public List getRelationshipPathAsList()
    {
        List list = FastList.newList();
        for(Mapper mapper : this.mappers)
        {
            if (mapper instanceof AbstractMapper)
            {
                AbstractMapper aMapper = (AbstractMapper) mapper;
                list.add(aMapper.getRawName());
            }
        }
        return list;
    }

    @Override
    public boolean isEstimatable()
    {
        return false;
    }

    public Mapper getCommonMapper(Mapper other)
    {
        if (other instanceof LinkedMapper)
        {
            LinkedMapper otherLinkedMapper = (LinkedMapper) other;
            int i=0;
            int end = Math.min(this.mappers.size(), otherLinkedMapper.mappers.size());
            while (i < end && this.mappers.get(i).equals(otherLinkedMapper.mappers.get(i)))
            {
                i++;
            }
            if (i == this.mappers.size()) return this;
            if (i > 0)
            {
                return new LinkedMapper(this.mappers.subList(0, i));
            }
        }
        else
        {
            if (this.mappers.get(0).equals(other))
            {
                return other;
            }
        }
        return null;
    }

    public Mapper getMapperRemainder(Mapper head)
    {

        if (head instanceof LinkedMapper)
        {
            LinkedMapper headLinkedMapper = (LinkedMapper) head;

            //not sure about this.
            if(headLinkedMapper.mappers.equals(this.mappers))
            {
                return null;
            }

            if (headLinkedMapper.mappers.size() == this.mappers.size() - 1)
            {
                return getLastMapper();
            }
            return new LinkedMapper(this.mappers.subList(headLinkedMapper.mappers.size(), this.mappers.size()));
        }
        else
        {
            List mapperList = this.mappers.subList(1, this.mappers.size());
            if(mapperList.size() > 1)
               return new LinkedMapper(mapperList);
            else
               return mapperList.get(0);
        }
    }

    public Function getParentSelectorRemainder(DeepRelationshipAttribute parentSelector)
    {
        parentSelector = parentSelector.copy();
        DeepRelationshipAttribute rootSelector = parentSelector;
        for(int i = 0; i < mappers.size(); i++)
        {
            rootSelector = rootSelector.getParentDeepRelationshipAttribute();
        }
        rootSelector.setParentDeepRelationshipAttribute(null);

        return parentSelector;
    }

    public Function getTopParentSelector(DeepRelationshipAttribute parentSelector)
    {
        DeepRelationshipAttribute topParentSelector = parentSelector;
        for(int i = 0; i < mappers.size(); i++)
        {
            topParentSelector = topParentSelector.getParentDeepRelationshipAttribute();

        }
        return topParentSelector;
    }

    public Operation createNotExistsOperation(Operation op)
    {
        Mapper headMapper;
        if (this.mappers.size() > 2)
        {
            Mapper[] headLinkedMappers = new Mapper[this.mappers.size() - 1];
            for(int i=0;i mappers = this.getMappers();
        Mapper m = new ChainedMapper(mappers.get(mappers.size() - 2), mappers.get(mappers.size() - 1));
        for(int i=mappers.size() - 3; i >= 0 ; i --)
        {
            m = new ChainedMapper(mappers.get(i), m);
        }
        return new NotExistsOperation(m, op);
    }

    private void addMapper(Mapper mapper)
    {
        if (mapper instanceof LinkedMapper)
        {
            this.mappers.addAll(((LinkedMapper)mapper).mappers);
        }
        else
        {
            this.mappers.add(mapper);
        }
    }

    public List getMappers()
    {
        return mappers;
    }

    public MithraObjectPortal getResultPortal()
    {
        Mapper mapper = this.mappers.get(0);
        return mapper.getResultPortal();
    }

    public MithraObjectPortal getFromPortal()
    {
        Mapper mapper = this.mappers.get(mappers.size()-1);
        return mapper.getFromPortal();
    }

    public boolean isReversible()
    {
        throw new RuntimeException("not implemented");
    }

    public boolean isJoinedWith(MithraObjectPortal portal)
    {
        for(int i=0;i=0 && joinedList != null;i--)
        {
            Mapper mapper = this.mappers.get(i);
            joinedList = mapper.map(joinedList);
        }
        return joinedList;
    }

    public ConcurrentFullUniqueIndex mapMinusOneLevel(List joinedList)
    {
        for(int i=this.mappers.size()-1;i>=1 && joinedList != null;i--)
        {
            Mapper mapper = this.mappers.get(i);
            joinedList = mapper.map(joinedList);
        }
        if (joinedList == null) return null;
        return this.mappers.get(0).mapMinusOneLevel(joinedList);
    }

    public List mapOne(Object joined, Operation extraLeftOperation)
    {
        List joinedList = ListFactory.create(joined);
        for(int i=this.mappers.size()-1;i>0 && joinedList != null;i--)
        {
            Mapper mapper = this.mappers.get(i);
            joinedList = mapper.map(joinedList);
        }
        if (joinedList != null)
        {
            FastList result = new FastList(joinedList.size());
            Mapper firstMapper = this.mappers.get(0);
            for(int i=0;i= 1)
        {
            Mapper parentMapper;
            if (splitPoint == 1)
            {
                parentMapper = this.mappers.get(0);
            }
            else
            {
                parentMapper = new LinkedMapper(this.mappers.subList(0, splitPoint));
            }

            Operation op = node.createMappedOperationForDeepFetch(parentMapper);
            if (op == null) return null;
            MithraList midParentList = op.getResultObjectPortal().getFinder().findMany(op);
            Mapper splitPointMapper = this.mappers.get(splitPoint);
            Operation simplifiedOp = splitPointMapper.getSimplifiedJoinOp(midParentList, maxInClause, node, useTuple);
            if (simplifiedOp != null)
            {
                for(int i=splitPoint+1;i tempOperationPool)
    {
        return getLastMapper().getOperationFromResult(result, tempOperationPool);
    }

    public Operation getOperationFromOriginal(Object original, Map tempOperationPool)
    {
        return getLastMapper().getOperationFromOriginal(original, tempOperationPool);
    }

    @Override
    public Operation getPrototypeOperation(Map tempOperationPool)
    {
        return getLastMapper().getPrototypeOperation(tempOperationPool);
    }

    public List getUnChainedMappers()
    {
        return getLastMapper().getUnChainedMappers();
    }

    public Operation createMappedOperationForDeepFetch(Operation op)
    {
        for(int i=0;i newList = new FastList(this.mappers.size()+ 1);
        newList.addAll(this.mappers);
        newList.add(other);
        return new LinkedMapper(newList);
    }

    @Override
    public List getAllPossibleResultObjectsForFullCache()
    {
        return this.mappers.get(0).getAllPossibleResultObjectsForFullCache();
    }

    public boolean hasLeftOrDefaultMappingsFor(AsOfAttribute[] leftAsOfAttributes)
    {
        return this.mappers.get(0).hasLeftOrDefaultMappingsFor(leftAsOfAttributes);
    }

    public boolean hasLeftMappingsFor(AsOfAttribute[] leftAsOfAttributes)
    {
        return this.mappers.get(0).hasLeftMappingsFor(leftAsOfAttributes);
    }

    public Attribute getAnyRightAttribute()
    {
        Mapper mapper = this.mappers.get(mappers.size()-1);
        return mapper.getAnyRightAttribute();
    }

    public Attribute getAnyLeftAttribute()
    {
        return this.mappers.get(0).getAnyLeftAttribute(); 
    }

    public boolean isFullyCachedIgnoringLeft()
    {
        boolean result = this.mappers.get(0).isFullyCachedIgnoringLeft();
        for(int i=1;result && i getAllLeftAttributes()
    {
        return this.getLastMapper().getAllLeftAttributes();
    }

    public Extractor[] getLeftAttributesWithoutFilters()
    {
        return this.getLastMapper().getLeftAttributesWithoutFilters();
    }

    public List filterLeftObjectList(List objects)
    {
        return this.getLastMapper().filterLeftObjectList(objects);
    }

    public Mapper createMapperForTempJoin(Map attributeMap, Object prototypeObject, int chainPosition)
    {
        return this.getLastMapper().createMapperForTempJoin(attributeMap, prototypeObject, chainPosition);
    }

    public boolean isMappableForTempJoin(Set attributeMap)
    {
        return this.getLastMapper().isMappableForTempJoin(attributeMap);
    }

    public double estimateMappingFactor()
    {
        throw new RuntimeException("not implemented");
    }

    @Override
    public int estimateMaxReturnSize(int multiplier)
    {
        throw new RuntimeException("not implemented");
    }

    public void registerEqualitiesAndAtomicOperations(TransitivePropagator transitivePropagator)
    {
        throw new RuntimeException("not implemented");
    }

    public boolean hasTriangleJoins()
    {
        for(int i=0;i reverseMappers = new FastList(this.mappers.size());
        for(int i=this.mappers.size() - 1;i>=0;i--)
        {
            Mapper mapper = this.mappers.get(i);
            Mapper revMappper = mapper.getReverseMapper();
            if (revMappper == null) return null;
            reverseMappers.add(revMappper);
        }
        return new LinkedMapper(reverseMappers);
    }

    public void addDepenedentPortalsToSet(Set set)
    {
        for(int i=0;i=0; j--)
        {
            this.mappers.get(j).popMappers(stack);
        }
        List newMappers = FastList.newList(this.mappers);
        newMappers.set(i, modifiedMapper);
        return new LinkedMapper(newMappers);
    }

    public Mapper insertOperationInMiddle(MapperStack insertPosition, InternalList toInsert, TransitivePropagator transitivePropagator)
    {
        throw new RuntimeException("not implemented");
    }

    public Mapper insertAsOfOperationOnLeft(AtomicOperation[] asOfEqOperations)
    {
        throw new RuntimeException("not implemented");
    }

    public Mapper insertOperationOnLeft(InternalList toInsert)
    {
        throw new RuntimeException("not implemented");
    }

    public void pushMappers(MapperStack mapperStack)
    {
        for(int i=0;i=0;i--)
        {
            Mapper mapper = this.mappers.get(i);
            mapper.popMappers(mapperStack);
        }
    }

    public void writeExternal(ObjectOutput out) throws IOException
    {
        out.writeInt(this.mappers.size());
        for(int i=0;i ignore)
    {
        return this.getLastMapper().getDefaultAsOfOperation(ignore);
    }

    public void setName(String name)
    {
        //ignore
    }

    public void appendName(StringBuilder stringBuilder)
    {
        stringBuilder.append("linkedMapper");
    }

    public void appendSyntheticName(StringBuilder stringBuilder)
    {
        stringBuilder.append("linkedMapper");
    }

    public boolean isSingleLevelJoin()
    {
        return false;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        LinkedMapper that = (LinkedMapper) o;

        if (!mappers.equals(that.mappers)) return false;

        return true;
    }

    @Override
    public int hashCode()
    {
        return HashUtil.combineHashes(mappers.get(0).hashCode(), mappers.get(mappers.size() - 1).hashCode());
    }

    @Override
    public void clearLeftOverFromObjectCache(Collection parentObjects, EqualityOperation extraEqOp, Operation extraOperation)
    {
        this.getLastMapper().clearLeftOverFromObjectCache(parentObjects, extraEqOp, extraOperation);
    }
}