com.netxforge.netxstudio.models.importer.MasterDataImporterBackup.java Source code

Java tutorial

Introduction

Here is the source code for com.netxforge.netxstudio.models.importer.MasterDataImporterBackup.java

Source

/*******************************************************************************
 * Copyright (c) May 20, 2011 NetXForge.
 *
 * This program 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *  You should have received a copy of the GNU Lesser General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>
 * 
 * Contributors: Martin Taal - initial API and implementation and/or
 * initial documentation
 *******************************************************************************/
package com.netxforge.netxstudio.models.importer;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.ExtendedMetaData;

import com.google.common.collect.Lists;
import com.netxforge.base.cdo.ICDOData;
import com.netxforge.netxstudio.library.Equipment;
import com.netxforge.netxstudio.library.Function;
import com.netxforge.netxstudio.library.LibraryPackage;
import com.netxforge.netxstudio.library.NodeType;
import com.netxforge.netxstudio.metrics.DataKind;
import com.netxforge.netxstudio.metrics.IdentifierDataKind;
import com.netxforge.netxstudio.metrics.KindHintType;
import com.netxforge.netxstudio.metrics.Mapping;
import com.netxforge.netxstudio.metrics.MappingColumn;
import com.netxforge.netxstudio.metrics.MetricSource;
import com.netxforge.netxstudio.metrics.ObjectKindType;
import com.netxforge.netxstudio.metrics.ValueDataKind;
import com.netxforge.netxstudio.metrics.ValueKindType;
import com.netxforge.netxstudio.services.Service;

/**
 * @author Martin Taal
 * @author Christophe Bouhier
 */
public class MasterDataImporterBackup {

    private ICDOData dataProvider;

    private EClass eClassToImport;

    /*
     * Maintains the end result, contained objects are gradually removed and
     * placed in the copied list for reference.
     */
    private List<IndexedObject> resultList = new ArrayList<IndexedObject>();

    /*
     * A contained object is put in this list for reference by index.
     */
    private List<IndexedObject> containedList = new ArrayList<IndexedObject>();

    private List<String> unresolvedReferences = new ArrayList<String>();

    private EPackage[] ePackagesToImport;

    private boolean indexSupport;

    public boolean isIndexSupport() {
        return indexSupport;
    }

    public void setIndexSupport(boolean indexSupport) {
        this.indexSupport = indexSupport;
    }

    class IndexedObject {
        public IndexedObject(String index, EObject eo) {
            this.eo = eo;
            this.index = index;
        }

        private EObject eo;
        private String index;

        public EObject getEObject() {
            return eo;
        }

        public void setEObject(EObject eo) {
            this.eo = eo;
        }

        public String getIndex() {
            return index;
        }

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

    public void process(InputStream is) {
        HSSFWorkbook workBook;
        try {
            workBook = new HSSFWorkbook(is);
            for (int i = 0; i < workBook.getNumberOfSheets(); i++) {

                ProcessWorkSheet pw = new ProcessWorkSheet(i, workBook.getSheetAt(i));
                List<RowResult> sheetResult = pw.getSheetResult();
                if (!pw.isMultiRefSheet()) {
                    for (final RowResult rowResult : sheetResult) {
                        EObject resultObject = EcoreUtil.copy(rowResult.getEObject());
                        IndexedObject io = new IndexedObject(rowResult.getIndex(), resultObject);
                        resultList.add(io);
                    }
                }
            }

            printResult();

        } catch (final Exception e) {
            throw new IllegalStateException(e);
        }
    }

    public List<EObject> getResolvedObjects() {

        List<EObject> result = Lists.newArrayList();

        for (IndexedObject io : resultList) {
            result.add(io.getEObject());
        }
        return result;
    }

    class ProcessWorkSheet {

        private List<EStructuralFeature> eFeatures = new ArrayList<EStructuralFeature>();

        final List<RowResult> sheetRowResults = new ArrayList<RowResult>();
        private boolean isMultiRefSheet = false;

        List<RowResult> getSheetResult() {
            return sheetRowResults;
        }

        boolean isMultiRefSheet() {
            return isMultiRefSheet;
        }

        /**
         * Process an .xls worksheet, each worksheet should match an EClass or
         * an EClass multiplicity references. From the EClass we generate the
         * EFeatures (EAttribute and EReference) which should correspond to the
         * columns of the sheet.
         * 
         * Next for each row an object, with the matching EClass is created or
         * looked up. Single ref sheets are populated and cached, while for
         * multi ref - sheets the object is looked EReferences).
         * 
         * @param index
         * @param sheet
         * @return
         */
        ProcessWorkSheet(int index, HSSFSheet sheet) {

            System.err.println("SHEET: " + sheet.getSheetName());

            // Match the features of this sheet.
            if (!setEFeatures(sheet)) {
                System.err.println("SHEET ABORT " + sheet.getSheetName()
                        + " No Class found for the context Packages" + ePackagesToImport);
                return;
            }

            // Keep track of the last resolved object for multiref sheets.
            EObject lastRootObject = null;

            // process non-empty rows, starting from 3nd row.
            for (int i = 2; i <= sheet.getLastRowNum(); i++) {
                HSSFRow row = sheet.getRow(i);
                if (isEmptyRow(row)) {
                    continue;
                }
                EObject eObject;
                if (eClassToImport != null) {
                    if (!isMultiRefSheet) {
                        String objectIndex = null;
                        if (indexSupport) {
                            objectIndex = this.processIndex(row);
                        }
                        eObject = processAttributes(row);
                        if (eObject != null) {

                            // Create a Row result.
                            final RowResult rowResult = new RowResult();
                            rowResult.setRow(sheet.getRow(i));
                            rowResult.setEObject(eObject);
                            if (objectIndex != null) {
                                rowResult.setIndex(objectIndex);
                            }
                            sheetRowResults.add(rowResult);

                            if (featuresHaveReferences()) {
                                eObject = processEReferences(false, rowResult.getEObject(), rowResult.getRow());
                            }

                        }
                    } else {
                        eObject = getMultiRefRowObject(lastRootObject, row);
                        if (eObject != null) {
                            eObject = processEReferences(true, eObject, row);
                        }
                    }
                    if (eObject != null && eObject.eContainer() == null) {
                        lastRootObject = eObject;
                        System.out.println(" LAST ROOT: " + printObject(lastRootObject));
                    }
                }
            }
        }

        private boolean featuresHaveReferences() {
            boolean hasReference = false;
            for (EStructuralFeature f : eFeatures) {
                if (f instanceof EReference) {
                    hasReference = true;
                }
            }
            return hasReference;
        }

        /**
         * Loop through the features of the target packages. Match the cell with
         * the EStructuralFeature name.
         * 
         * @param sheet
         */
        private boolean setEFeatures(HSSFSheet sheet) {

            eFeatures.clear();
            isMultiRefSheet = setEClassFromSheetName(sheet);

            if (eClassToImport == null) {
                return false; // We need an EClass.
            }
            if (sheet.getRow(0) == null) {
                return false; // We need a first row.
            }

            // Process each column from row 0, and find the corresponding
            // feature.
            // When found.
            final Iterator<Cell> iterator = sheet.getRow(0).cellIterator();
            while (iterator.hasNext()) {

                Cell c = iterator.next();
                if (isMultiRefSheet && c.getColumnIndex() == 0) {
                    // skip the first column
                    continue;
                }

                int currentFeatureCount = eFeatures.size();
                final String name = c.getStringCellValue();
                for (final EStructuralFeature eFeature : eClassToImport.getEAllStructuralFeatures()) {
                    if (name.toLowerCase().equals(eFeature.getName().toLowerCase())) {
                        System.out.println("  FEATURE -> Add Feature=" + c.getColumnIndex() + ", Value=" + name);
                        eFeatures.add(eFeature);
                        break;
                    } else {

                    }
                }
                // We haven't added a feature.
                if (currentFeatureCount == eFeatures.size()) {
                    System.out.println("  FEATURE -> Skipped Column=" + c.getColumnIndex() + ", Value=" + name);
                }
            }
            return true;
        }

        private String processIndex(HSSFRow row) {
            if (row == null) {
                return null;
            }
            if (isEmptyRow(row)) {
                return null;
            }
            String value = row.getCell(0).getStringCellValue();
            return value;
        }

        /**
         * Create an object for each non-empty row, then populate the attributes
         * and single refs using the features (Which have been set previously).
         * Note: we also consider the max length of the value which can be
         * stored.
         * 
         * @param row
         * @return
         */
        private EObject processAttributes(HSSFRow row) {

            if (row == null) {
                return null;
            }
            if (isEmptyRow(row)) {
                return null;
            }

            System.out.println(" CREATE: " + eClassToImport.getName());
            final EObject result = EcoreUtil.create(eClassToImport);
            for (int i = 0; i < eFeatures.size(); i++) {
                final EStructuralFeature eFeature = eFeatures.get(i);

                int index = indexSupport ? i + 1 : i;
                System.out.print(" ROW(A)=" + row.getRowNum() + " , COL= " + index);
                HSSFCell cell = row.getCell(index);
                if (cell == null) {
                    System.out.println(" -> WRONG Value=\"empty\"");
                    continue;
                }
                if (eFeature instanceof EReference) {
                    System.out.println(" -> Skip, Reference=" + eFeature.getName());
                    continue;
                } else if (eFeature instanceof EAttribute) {

                    if (eFeature == LibraryPackage.Literals.EXPRESSION__EXPRESSION_LINES) {
                        // FIXME, doesn't work for this feature.
                        System.out.println("debug here");
                        continue;
                    }

                    System.out.print(" -> OK Attribute=" + eFeature.getName());
                    EAttribute eAttrib = (EAttribute) eFeature;
                    EDataType type = eAttrib.getEAttributeType();

                    // Get the value.
                    String value = cell.getStringCellValue();
                    if (value == null || value.trim().length() == 0) {
                        System.out.println(" , WRONG Value=\"empty\"");
                        continue;
                    }

                    // Trim the value to the maxfacet Length.
                    final int maxLength = ExtendedMetaData.INSTANCE.getMaxLengthFacet(eAttrib.getEAttributeType());
                    if (maxLength > 0 && value != null && value.length() > maxLength) {
                        System.out.print(" , trim to=" + maxLength);
                        value = value.substring(0, maxLength);
                    }

                    // Resolve the type and set the attrib value.
                    if (type.getInstanceClass() == String.class) {
                        result.eSet(eFeature, value);
                    } else if (type.getInstanceClass() == boolean.class) {
                        Boolean bValue = new Boolean(value);
                        result.eSet(eFeature, bValue);
                    } else if (type.getInstanceClass() == int.class) {
                        Integer iValue = new Integer(value);
                        result.eSet(eFeature, iValue);
                    }

                    // ///// ENUMS WHICH ARE MODE SPECIFIC.
                    else if (type.getInstanceClass() == ObjectKindType.class) {
                        ObjectKindType ok = ObjectKindType.get(value);
                        result.eSet(eFeature, ok);
                    }
                    if (type.getInstanceClass() == ValueKindType.class) {
                        ValueKindType vk = ValueKindType.get(value);
                        result.eSet(eFeature, vk);
                    }
                    if (type.getInstanceClass() == KindHintType.class) {
                        KindHintType kht = KindHintType.get(value);
                        result.eSet(eFeature, kht);
                    }
                    System.out.println(" , Type=" + type.getInstanceClassName() + ", Value=\"" + value + "\"");
                } else {
                    System.out.println("Some other structural feature");
                }

            }
            return result;
        }

        /**
         * 
         * @param row
         * @return
         */
        private EObject getMultiRefRowObject(EObject parent, HSSFRow row) {
            if (row == null) {
                return null;
            }
            if (isEmptyRow(row)) {
                return null;
            }
            // The identifier is the first column for a MultiRef row.
            String identifier = row.getCell(0).getStringCellValue();
            EObject targetObject = getReferencedObject(parent, eClassToImport, identifier);
            if (targetObject == null) {
                targetObject = getReferencedObjectFromContainment(parent, eClassToImport, identifier);
                if (targetObject != null) {
                    if (targetObject.eContainer() == null) {
                        System.err.println("ERROR: Contained object has no container??");
                    }
                } else {
                    notFound(eClassToImport, identifier);
                }
            }
            return targetObject;
        }

        private EObject processEReferences(boolean isMultiRef, EObject targetObject, HSSFRow row) {

            if (row == null) {
                return null;
            }
            if (isEmptyRow(row)) {
                return null;
            }

            System.out.println(" REFS FOR: " + eClassToImport.getName());
            for (int i = 0; i < eFeatures.size(); i++) {

                final EStructuralFeature eFeature = eFeatures.get(i);
                int index = (isMultiRef | isIndexSupport()) ? i + 1 : i;

                System.out.print(" ROW(" + (isMultiRef ? "MR" : "R") + ")=" + row.getRowNum() + " , COL= " + index);
                if (row.getCell(index) == null) {
                    System.out.println(" ,Value=\"empty\"");
                    continue;
                }
                if (eFeature instanceof EAttribute) {
                    System.out.println(" -> Skip, Attribute=" + eFeature.getName());
                    continue;
                } else if (eFeature instanceof EReference) {

                    System.out.print(" -> OK Reference=" + eFeature.getName());

                    // Get the value.
                    final String indexValue = row.getCell(index).getStringCellValue();

                    if (indexValue == null || indexValue.trim().length() == 0) {
                        System.out.println(" ,WRONG Value=\"empty\"");
                        continue;
                    }

                    System.out.println(" , ref index=" + indexValue);
                    final EReference eReference = (EReference) eFeature;

                    // Get the referenced object.
                    EObject objectToSet = getReferencedObject(null, eReference.getEReferenceType(), indexValue);
                    if (objectToSet != null) {
                        storeReference(true, indexValue, targetObject, eReference, objectToSet);
                    } else {
                        if ((objectToSet = getReferencedObjectFromContainment(null, eReference.getEReferenceType(),
                                indexValue)) != null) {
                            storeReference(false, indexValue, targetObject, eReference, objectToSet);
                        } else {
                            notFound(eClassToImport, indexValue);
                        }
                    }
                }
            }
            return targetObject;
        }
    }

    private void storeReference(boolean copyObjectForContainment, String indexValue, EObject target,
            final EReference eReference, EObject objectToSet) {

        EClassifier eType = eReference.getEType();
        if (eType.eClass().equals(objectToSet.eClass())) {
            System.out.println("Reference to be set matching type: " + eType);
        }

        if (eReference.isMany()) {
            // Process many values

            @SuppressWarnings("unchecked")
            EList<EObject> manyReference = (EList<EObject>) target.eGet(eReference);
            Collection<EObject> copyAll = EcoreUtil.copyAll(manyReference);

            // For containments, we set as a
            // reference and
            // then move it from the result set to the
            // For Non-Containments we simply set a reference to the object to
            // set (Which might
            // still be in the result set).
            if (eReference.isContainment()) {

                System.out.println("  SET REF MULTI(Containment): " + printObject(objectToSet) + " with eRef: "
                        + eReference.getName() + " , on object:" + printObject(target));

                System.out.println("  MOVE from result set to contained set: " + printObject(objectToSet));

                if (copyObjectForContainment) {
                    EObject copyOfObjectToSet = EcoreUtil.copy(objectToSet);
                    copyAll.add(copyOfObjectToSet);
                    removeObjectFromResultSet(objectToSet);
                    addObjectToContainedSet(indexValue, copyOfObjectToSet);
                } else {
                    copyAll.add(objectToSet);
                }

            } else {
                System.out.println(" SET REF MULTI (NON-Containment): " + printObject(objectToSet) + " with eRef: "
                        + eReference.getName() + " , on object:" + printObject(target));
                copyAll.add(objectToSet);
            }
            target.eSet(eReference, copyAll);

        } else {
            if (eReference.isContainment()) {

                System.out.println("  SET REF SINGLE(Containment): " + printObject(objectToSet) + " with eRef: "
                        + eReference.getName() + " , on object:" + printObject(target));

                System.out.println("  MOVE from result set to contained set: " + printObject(objectToSet));

                if (copyObjectForContainment) {
                    EObject copyOfObjectToSet = EcoreUtil.copy(objectToSet);
                    target.eSet(eReference, copyOfObjectToSet);
                    removeObjectFromResultSet(objectToSet);
                    addObjectToContainedSet(indexValue, copyOfObjectToSet);
                } else {
                    target.eSet(eReference, objectToSet);
                }

            } else {
                System.out.println("  SET REF SINGLE (NON-Containment): " + printObject(objectToSet)
                        + " with eRef: " + eReference.getName() + " , on object:" + printObject(target));
                target.eSet(eReference, objectToSet);
            }
        }
    }

    private boolean setEClassFromSheetName(HSSFSheet sheet) {
        String name = sheet.getSheetName();
        for (int i = 0; i < this.ePackagesToImport.length; i++) {
            EPackage ePackage = ePackagesToImport[i];
            for (EClassifier classifier : ePackage.getEClassifiers()) {
                if (classifier instanceof EClass) {
                    String cName = ((EClass) classifier).getName();
                    if (cName.equalsIgnoreCase(name)) {

                        eClassToImport = (EClass) classifier;
                        System.out.println("CLASS REF: " + eClassToImport.getName());
                    }
                    cName = cName + "_refs";
                    if (cName.equalsIgnoreCase(name)) {
                        eClassToImport = (EClass) classifier;
                        System.out.println("CLASS MULTI_REF: " + eClassToImport.getName());
                        return true;
                    }
                }
            }
        }
        return false;
    }

    private boolean isEmptyRow(HSSFRow row) {
        if (row == null) {
            return true;
        }
        final Iterator<Cell> cellIterator = row.cellIterator();
        while (cellIterator.hasNext()) {
            final Cell cell = cellIterator.next();
            final String value = cell.getStringCellValue();
            if (value != null && value.trim().length() > 0) {
                return false;
            }
        }
        return true;
    }

    public void setEPackagesToImport(EPackage... ePackagesToImport) {
        this.ePackagesToImport = ePackagesToImport;
    }

    public ICDOData getDataProvider() {
        return dataProvider;
    }

    public void setDataProvider(ICDOData dataProvider) {
        this.dataProvider = dataProvider;
    }

    /**
     * Should find an object within this hierarchy root, the eContainer of the
     * root should not be set, otherwise we would be fishing on a branch. if
     * there is no root, look in the total set, and finally produce a new node
     * from the cache.
     * 
     * @param root
     * @param eClass
     * @param identifier
     * @return
     */
    private EObject getReferencedObject(EObject root, EClass eClass, String identifier) {

        EObject result = null;
        System.out.print("  RESOLVING: " + identifier);
        if (root != null && root.eContainer() == null) {

            System.out.print("  , in root: " + printObject(root));

            // Is it a child in the result set?
            Iterator<EObject> it = null;
            it = root.eAllContents();
            while (it.hasNext()) {
                final EObject eObject = it.next();
                if (isAnyOfTheSuperTypes(eObject, eClass)) {
                    if (matchesAnyAttribute(identifier, eObject)) {
                        System.out.print(", found!=" + printObject(eObject));
                        return eObject;
                    }
                }
            }
            System.out.println(" , not (yet) found in root...");
        }

        // If we don't have a root object, we look in the full result set
        // for the occurence. (the object will already have hierarchy).
        //
        IndexedObject indexedObject = null;
        if (this.indexSupport) {
            System.out.print("  , look in complete result set");
            indexedObject = this.findObject(identifier, this.resultList);
        } else {
            indexedObject = this.findObject(eClass, identifier);
        }

        if (indexedObject != null) {
            System.out.println(", found!=\"" + printObject(indexedObject.getEObject()) + "\"");
            return indexedObject.getEObject();
        }

        return result;
    }

    private EObject getReferencedObjectFromContainment(EObject root, EClass eClass, String identifier) {

        EObject result = null;
        System.out.print("  RESOLVING: " + identifier);
        if (root != null && root.eContainer() == null) {

            System.out.print("  , in root: " + printObject(root));

            // Is it a child in the result set?
            Iterator<EObject> it = null;
            it = root.eAllContents();
            while (it.hasNext()) {
                final EObject eObject = it.next();
                if (isAnyOfTheSuperTypes(eObject, eClass)) {
                    if (matchesAnyAttribute(identifier, eObject)) {
                        System.out.print(", found!=" + printObject(eObject));
                        return eObject;
                    }
                }
            }
            System.out.println(" , not (yet) found in root...");
        }

        // If we don't have a root object, we look in the full result set
        // for the occurence. (the object will already have hierarchy).
        //
        IndexedObject indexedObject = null;
        if (this.indexSupport) {
            System.out.print(" look in in contained set");
            indexedObject = this.findObject(identifier, this.containedList);
        } else {
            indexedObject = this.findObject(eClass, identifier);
        }

        if (indexedObject != null) {
            System.out.println(", found!=\"" + printObject(indexedObject.getEObject()) + "\"");
            return indexedObject.getEObject();
        }
        return result;
    }

    /*
     * Find an object in a specified indexed object list.
     */
    private IndexedObject findObject(String identifier, List<IndexedObject> searchList) {
        IndexedObject ioResult = null;
        for (IndexedObject io : searchList) {
            if (io.getIndex().equals(identifier)) {
                ioResult = io;
                break;
            }
        }
        return ioResult;
    }

    public void notFound(EClass eClass, String identifier) {
        System.err.print(", NOT found!, Check the sheet, Is the order of the sheets correct?, ");
        unresolvedReferences.add(eClass.getName() + " using " + identifier);
    }

    /**
     * Find using any of the attributes from the class and the identifier.
     * 
     * @param eClass
     * @param identifier
     * @return
     */
    private IndexedObject findObject(EClass eClass, String identifier) {
        IndexedObject ioResult = null;
        for (IndexedObject io : this.resultList) {
            EObject eObject = io.getEObject();
            if (isAnyOfTheSuperTypes(eObject, eClass)) {
                if (matchesAnyAttribute(identifier, eObject)) {
                    return io;
                }
            }
        }
        return ioResult;
    }

    private void removeObjectFromResultSet(EObject eo) {
        int index = -1;
        for (IndexedObject io : this.resultList) {
            if (io.getEObject() == eo) {
                index = this.resultList.indexOf(io);
            }
        }
        if (index != -1) {
            resultList.get(index);
            resultList.remove(index);
        } else {
            System.out.println(
                    "ERROR, Moving object from result set to contained set, the object to move doesn't exist in the result set!");
        }

    }

    private void addObjectToContainedSet(String indexValue, EObject eo) {
        IndexedObject findObject = this.findObject(indexValue, this.containedList);
        if (findObject == null) {
            eo.hashCode();
            findObject = new IndexedObject(indexValue, eo);
            this.containedList.add(findObject);
        }
    }

    private boolean isAnyOfTheSuperTypes(EObject eObject, EClass eClass) {

        List<EClass> classes = Lists.newArrayList(eObject.eClass());
        classes.addAll(eObject.eClass().getEAllSuperTypes());
        for (EClass c : classes) {
            if (eClass.getName().equals(c.getName())) {
                return true;
            }
        }
        return false;
    }

    private boolean matchesAnyAttribute(String identifier, final EObject eObject) {
        for (final EAttribute eAttribute : eObject.eClass().getEAllAttributes()) {
            final Object value = eObject.eGet(eAttribute);
            if (value instanceof String && ((String) value).compareToIgnoreCase(identifier) == 0) {
                System.out.println("  Found object for : " + identifier + " object: " + printObject(eObject));
                return true;
            }
        }
        return false;
    }

    public class RowResult {
        private HSSFRow row;
        private EObject eObject;
        private String index;

        public HSSFRow getRow() {
            return row;
        }

        public void setRow(HSSFRow row) {
            this.row = row;
        }

        public EObject getEObject() {
            return eObject;
        }

        public void setEObject(EObject eObject) {
            this.eObject = eObject;
        }

        public String getIndex() {
            return index;
        }

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

    private void printResult() {

        // TODO FIX.
        // System.out.println("The STRUCTURED result");
        // for (IndexedObject io : structuredResult) {
        // String print = this.printObject(0, io.getEObject());
        // System.out.println(print);
        // }
        System.out.println("The UNRESOLVED references ");
        for (String s : unresolvedReferences) {
            System.out.println(" Unresolved identifier : " + s);
        }
    }

    private String printObject(EObject o) {
        return printObject(0, o);
    }

    private String printObject(int depth, EObject o) {
        depth++;
        StringBuilder result = new StringBuilder();
        if (o instanceof Equipment) {
            result.append(depth(depth) + ((Equipment) o).getEquipmentCode());
            for (Equipment e : ((Equipment) o).getEquipments()) {
                printObject(depth, e);
            }
        }
        if (o instanceof Function) {
            result.append(depth(depth) + (((Function) o).getName()));
            for (Function e : ((Function) o).getFunctions()) {
                printObject(depth, e);
            }
        }
        if (o instanceof NodeType) {
            NodeType nt = (NodeType) o;
            result.append(depth(depth) + nt.getName());

            for (Function e : ((NodeType) nt).getFunctions()) {
                printObject(depth, e);
            }

            for (Equipment e : ((NodeType) nt).getEquipments()) {
                printObject(depth, e);
            }
        }
        if (o instanceof Service) {
            Service nt = (Service) o;
            result.append(nt.getServiceName());
            for (Service s : nt.getServices()) {
                result.append(this.printObject(depth, s));
            }
        }

        if (o instanceof MetricSource) {
            MetricSource ms = (MetricSource) o;
            result.append(ms.getName());
            result.append(this.printObject(depth, ms.getMetricMapping()));
        }
        if (o instanceof Mapping) {
            Mapping mapping = (Mapping) o;
            result.append("mapping");
            for (MappingColumn mc : mapping.getDataMappingColumns()) {
                result.append(this.printObject(depth, mc));
            }
        }
        if (o instanceof MappingColumn) {
            MappingColumn mc = (MappingColumn) o;
            result.append("mapping column: " + mc.getColumn());
            result.append(printObject(depth, mc.getDataType()));
        }
        if (o instanceof DataKind) {
            DataKind dk = (DataKind) o;
            if (dk instanceof IdentifierDataKind) {
                result.append("Identifier Datakind: " + ((IdentifierDataKind) dk).getObjectKind());
            }
            if (dk instanceof ValueDataKind) {
                result.append("Value Datakind: " + ((ValueDataKind) dk).getValueKind());
            }
        }

        return result.toString();
    }

    String depth(int depth) {
        char[] chars = new char[depth];
        for (int i = 0; i < chars.length; i++) {
            chars[i] = '-';
        }
        return chars.toString();
    }

}