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

com.orientechnologies.orient.core.sql.OFindReferenceHelper Maven / Gradle / Ivy

/*
 *
 *  *  Copyright 2014 Orient Technologies LTD (info(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.
 *  *
 *  * For more information: http://www.orientechnologies.com
 *
 */
package com.orientechnologies.orient.core.sql;

import java.util.*;
import java.util.Map.Entry;

import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.object.OLazyObjectListInterface;
import com.orientechnologies.orient.core.db.object.OLazyObjectMapInterface;
import com.orientechnologies.orient.core.db.object.OLazyObjectSetInterface;
import com.orientechnologies.orient.core.db.record.OIdentifiable;
import com.orientechnologies.orient.core.db.record.ORecordLazyMap;
import com.orientechnologies.orient.core.db.record.ORecordLazyMultiValue;
import com.orientechnologies.orient.core.exception.OCommandExecutionException;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.metadata.OMetadataInternal;
import com.orientechnologies.orient.core.metadata.schema.OClass;
import com.orientechnologies.orient.core.record.ORecord;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.serialization.serializer.OStringSerializerHelper;

/**
 * Helper class to find reference in records.
 * 
 * @author Luca Garulli (l.garulli--at--orientechnologies.com)
 * @author Luca Molino
 * 
 */
public class OFindReferenceHelper {

  public static List findReferences(final Set iRecordIds, final String classList) {
    final ODatabaseDocument db = ODatabaseRecordThreadLocal.INSTANCE.get();

    final Map> map = new HashMap>();
    for (ORID rid : iRecordIds) {
      map.put(rid, new HashSet());
    }

    if (classList == null || classList.isEmpty()) {
      for (String clusterName : db.getClusterNames()) {
        browseCluster(db, iRecordIds, map, clusterName);
      }
    } else {
      final List classes = OStringSerializerHelper.smartSplit(classList, ',');
      for (String clazz : classes) {
        if (clazz.startsWith("CLUSTER:")) {
          browseCluster(db, iRecordIds, map, clazz.substring(clazz.indexOf("CLUSTER:") + "CLUSTER:".length()));
        } else {
          browseClass(db, iRecordIds, map, clazz);
        }
      }
    }

    final List result = new ArrayList();
    for (Entry> entry : map.entrySet()) {
      final ODocument doc = new ODocument();
      result.add(doc);

      doc.field("rid", entry.getKey());
      doc.field("referredBy", entry.getValue());
    }

    return result;
  }

  private static void browseCluster(final ODatabaseDocument iDatabase, final Set iSourceRIDs, final Map> map,
      final String iClusterName) {
    for (ORecord record : iDatabase.browseCluster(iClusterName)) {
      if (record instanceof ODocument) {
        try {
          for (String fieldName : ((ODocument) record).fieldNames()) {
            Object value = ((ODocument) record).field(fieldName);
            checkObject(iSourceRIDs, map, value, (ODocument) record);
          }
        } catch (Exception e) {
          OLogManager.instance().debug(null, "Error reading record " + record.getIdentity(), e);
        }
      }
    }
  }

  private static void browseClass(final ODatabaseDocument db, Set iSourceRIDs, final Map> map,
      final String iClassName) {
    final OClass clazz = ((OMetadataInternal)db.getMetadata()).getImmutableSchemaSnapshot().getClass(iClassName);

    if (clazz == null)
      throw new OCommandExecutionException("Class '" + iClassName + "' was not found");

    for (int i : clazz.getClusterIds()) {
      browseCluster(db, iSourceRIDs, map, db.getClusterNameById(i));
    }
  }

  private static void checkObject(final Set iSourceRIDs, final Map> map, final Object value,
      final ORecord iRootObject) {
    if (value instanceof OIdentifiable) {
      checkRecord(iSourceRIDs, map, (OIdentifiable) value, iRootObject);
    } else if (value instanceof Collection) {
      checkCollection(iSourceRIDs, map, (Collection) value, iRootObject);
    } else if (value instanceof Map) {
      checkMap(iSourceRIDs, map, (Map) value, iRootObject);
    }
  }

  private static void checkCollection(final Set iSourceRIDs, final Map> map, final Collection values,
      final ORecord iRootObject) {
    final Iterator it;
    if (values instanceof OLazyObjectListInterface) {
      ((OLazyObjectListInterface) values).setConvertToRecord(false);
      it = ((OLazyObjectListInterface) values).listIterator();
    } else if (values instanceof OLazyObjectSetInterface) {
      ((OLazyObjectSetInterface) values).setConvertToRecord(false);
      it = ((OLazyObjectSetInterface) values).iterator();
    } else if (values instanceof ORecordLazyMultiValue) {
      it = ((ORecordLazyMultiValue) values).rawIterator();
    } else {
      it = values.iterator();
    }
    while (it.hasNext()) {
      checkObject(iSourceRIDs, map, it.next(), iRootObject);
    }
  }

  private static void checkMap(final Set iSourceRIDs, final Map> map, final Map values,
      final ORecord iRootObject) {
    final Iterator it;
    if (values instanceof OLazyObjectMapInterface) {
      ((OLazyObjectMapInterface) values).setConvertToRecord(false);
      it = ((OLazyObjectMapInterface) values).values().iterator();
    } else if (values instanceof ORecordLazyMap) {
      it = ((ORecordLazyMap) values).rawIterator();
    } else {
      it = values.values().iterator();
    }
    while (it.hasNext()) {
      checkObject(iSourceRIDs, map, it.next(), iRootObject);
    }
  }

  private static void checkRecord(final Set iSourceRIDs, final Map> map, final OIdentifiable value,
      final ORecord iRootObject) {
    if (iSourceRIDs.contains(value.getIdentity()))
      map.get(value.getIdentity()).add(iRootObject.getIdentity());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy