Package com.orientechnologies.orient.core.fetch

Source Code of com.orientechnologies.orient.core.fetch.OFetchHelper

/*
* Copyright 1999-2010 Luca Garulli (l.garulli--at--orientechnologies.com)
*
* 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.orientechnologies.orient.core.fetch;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.orient.core.exception.ORecordNotFoundException;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper;

/**
* Helper class for fetching.
*
* @author Luca Garulli
*
*/
public class OFetchHelper {
  private static final String  ANY_FIELD  = "*";

  public static Map<String, Integer> buildFetchPlan(final String iFetchPlan) {
    final Map<String, Integer> fetchPlan;

    if (iFetchPlan != null) {
      // CHECK IF THERE IS SOME FETCH-DEPTH
      final List<String> planParts = OStringSerializerHelper.split(iFetchPlan, ' ');
      if (planParts.size() > 0) {
        fetchPlan = new HashMap<String, Integer>();

        List<String> parts;
        for (String planPart : planParts) {
          parts = OStringSerializerHelper.split(planPart, ':');
          fetchPlan.put(parts.get(0), Integer.parseInt(parts.get(1)));
        }
      } else {
        fetchPlan = null;
      }
    } else
      fetchPlan = null;

    return fetchPlan;
  }

  @SuppressWarnings("unchecked")
  public static void fetch(final ODocument iRootRecord, final Object iUserObject, final Map<String, Integer> iFetchPlan,
      final String iCurrentField, final int iCurrentLevel, final int iMaxFetch, final OFetchListener iListener) {

    if (iMaxFetch > -1 && iListener.size() >= iMaxFetch)
      // MAX FETCH SIZE REACHED: STOP TO FETCH AT ALL
      return;

    Object fieldValue;
    Integer depthLevel;
    final Integer anyFieldDepthLevel = (iFetchPlan != null && iFetchPlan.get(ANY_FIELD) != null) ? iFetchPlan.get(ANY_FIELD)
        : Integer.valueOf(0);
    try {
      // BROWSE ALL THE DOCUMENT'S FIELDS
      for (String fieldName : iRootRecord.fieldNames()) {
        fieldValue = iRootRecord.field(fieldName);

        if (fieldValue == null
            || !(fieldValue instanceof ODocument)
            && (!(fieldValue instanceof Collection<?>) || (((Collection<?>) fieldValue).size() > 0 && !(((Collection<?>) fieldValue)
                .iterator().next() instanceof ODocument)))
            && (!(fieldValue instanceof Map<?, ?>) || (((Map<?, ?>) fieldValue).size() > 0 && !(((Map<?, ?>) fieldValue).values()
                .iterator().next() instanceof ODocument))))
          // NULL NEITHER LINK, NOR COLLECTION OF LINKS OR MAP OF LINKS
          continue;

        depthLevel = getDepthLevel(iRootRecord, iFetchPlan, fieldName);

        if (depthLevel == null)
          // NO SPECIFIED: ASSIGN DEFAULT LEVEL TAKEN FROM * WILDCARD IF ANY
          depthLevel = anyFieldDepthLevel;

        if (depthLevel == 0)
          // NO FETCH THIS FIELD PLEASE
          continue;

        if (depthLevel > -1 && iCurrentLevel >= depthLevel)
          // MAX DEPTH REACHED: STOP TO FETCH THIS FIELD
          continue;

        Object userObject;
        if (fieldValue instanceof ODocument) {
          final ODocument linked = (ODocument) fieldValue;
          try {
            userObject = iListener.fetchLinked(iRootRecord, iUserObject, fieldName, linked);
            if (userObject != null)
              // GO RECURSIVELY
              fetch(linked, userObject, iFetchPlan, fieldName, iCurrentLevel + 1, iMaxFetch, iListener);
          } catch (ORecordNotFoundException e) {
            OLogManager.instance().error(null, "Linked record %s was not found", linked);
          }

        } else if (fieldValue instanceof Collection<?>) {
          final Collection<ODocument> linked = (Collection<ODocument>) fieldValue;
          userObject = iListener.fetchLinked(iRootRecord, iUserObject, fieldName, linked);
          if (userObject != null)
            for (ODocument d : (Collection<ODocument>) userObject) {
              // GO RECURSIVELY
              if (d != null)
                fetch(d, d, iFetchPlan, fieldName, iCurrentLevel + 1, iMaxFetch, iListener);
            }
        } else if (fieldValue instanceof Map<?, ?>) {
          final Map<String, ODocument> linked = (Map<String, ODocument>) fieldValue;
          userObject = iListener.fetchLinked(iRootRecord, iUserObject, fieldName, linked);
          if (userObject != null)
            for (ODocument d : ((Map<String, ODocument>) userObject).values()) {
              // GO RECURSIVELY
              if (d != null)
                fetch(d, d, iFetchPlan, fieldName, iCurrentLevel + 1, iMaxFetch, iListener);
            }
        }

        if (iMaxFetch > -1 && iListener.size() >= iMaxFetch)
          // MAX FETCH SIZE REACHED: STOP TO FETCH AT ALL
          return;
      }
    } catch (Exception e) {
      e.printStackTrace();
      OLogManager.instance().error(null, "Fetching error on record %s", e, iRootRecord.getIdentity());
    }
  }

  public static void checkFetchPlanValid(final String iFetchPlan) {

    if (iFetchPlan != null && iFetchPlan.length() > 0) {
      // CHECK IF THERE IS SOME FETCH-DEPTH
      final List<String> planParts = OStringSerializerHelper.split(iFetchPlan, ' ');
      if (planParts.size() > 0) {
        for (String planPart : planParts) {
          final List<String> parts = OStringSerializerHelper.split(planPart, ':');
          if (parts.size() != 2) {
            throw new IllegalArgumentException("Fetch plan '" + iFetchPlan + "' is invalid");
          }
        }
      } else {
        throw new IllegalArgumentException("Fetch plan '" + iFetchPlan + "' is invalid");
      }
    }

  }

  public static boolean isFetchPlanValid(final String iFetchPlan) {

    if (iFetchPlan != null && iFetchPlan.length() > 0) {
      // CHECK IF THERE IS SOME FETCH-DEPTH
      final List<String> planParts = OStringSerializerHelper.split(iFetchPlan, ' ');
      if (planParts.size() > 0) {
        for (String planPart : planParts) {
          final List<String> parts = OStringSerializerHelper.split(planPart, ':');
          if (parts.size() != 2) {
            return false;
          }
        }
      } else {
        return false;
      }
    }

    return true;

  }

  private static Integer getDepthLevel(final ODocument doc, final Map<String, Integer> iFetchPlan, final String iFieldName) {
    Integer depthLevel;

    if (iFetchPlan != null) {
      // GET THE FETCH PLAN FOR THE GENERIC FIELD IF SPECIFIED
      depthLevel = iFetchPlan.get(iFieldName);

      if (depthLevel == null) {
        OClass cls = doc.getSchemaClass();
        while (cls != null && depthLevel == null) {
          depthLevel = iFetchPlan.get(cls.getName() + "." + iFieldName);

          if (depthLevel == null)
            cls = cls.getSuperClass();
        }
      }
    } else
      // INFINITE
      depthLevel = -1;

    return depthLevel;
  }
}
TOP

Related Classes of com.orientechnologies.orient.core.fetch.OFetchHelper

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.