occiware / OCCI-Studio

OCCI Studio
Eclipse Public License 1.0
11 stars 2 forks source link

How to set attributes Complex types (ArrayType and RecordType) programmatically using entity interface and OCCIHelper #24

Open cgourdin opened 6 years ago

cgourdin commented 6 years ago

Hello,

Objective : Implement complex datatypes on MartServer. I have problems setting attributes with OCCIHelper, complex type are not eAttributeType but are ReferenceImpl type, i use OCCIHelper.setAttributes method with AttributeStates object but for complex type i can't pass attributeStates because its not a generic attribute type. It throws IllegalArgumentException : Ecore structural feature 'arrayTest' is not an Ecore attribute! My extension is set as this :

capture d ecran 2017-10-29 a 09 52 43

I have another question : For my rendering output with json i need an ecore eValue object, as i don't have an EAttributeType, i can't obtain the instance value of the attribute. for Example i want to render from my extension : arrayTest and counterRecord from my entity.

/**
     * Read attributes from entity (used by link and resource) from attributeState list and return an attribute map.
     * @param readAttrs
     * @param entity
     * @return
     */
    private Map<String, Object> readAttributesToAttributesMap(final List<AttributeState> readAttrs, final Entity entity) {
        Map<String, Object> attributes = new LinkedHashMap<>();
        for (AttributeState attr : readAttrs) {
            String key = attr.getName();
            String val = attr.getValue();
            boolean complexType = false;
            if (val != null) {
                if (!key.equals(Constants.OCCI_CORE_SUMMARY) && !key.equals(Constants.OCCI_CORE_TITLE)
                        && !key.equals(Constants.OCCI_CORE_ID)
                        && !key.equals(Constants.OCCI_CORE_SOURCE)
                        && !key.equals(Constants.OCCI_CORE_TARGET)) {

                    EDataType eAttrType = null;

                    // Determine attribute type.
                    Optional<EDataType> optEDataType = EntityManager.getEAttributeType(entity, key);
                    Optional<Object> optEValue = EntityManager.getEMFValueObject(entity, key);
                    Object eValue = null;

                    if (optEValue.isPresent()) {
                        eValue = optEValue.get();
                    }
                    if (optEDataType.isPresent()) {
                        eAttrType = optEDataType.get();
                    }
                    // Specific to EEnum, must be rendered as String.
                    if (eAttrType != null && eAttrType instanceof EEnum) {
                        System.out.println("Attribute : " + key + " is an enum, render as String, value : " + val);
                        attributes.put(key, val);
                        continue;
                    }

                    if (eAttrType == null) {
                        LOGGER.warn("Unknown type for attribute: " + key + " value: " + val);
                        // Display as a string for all others.
                        attributes.put(key, val);
                        continue;
                    }
                    if (eValue == null) {
                        // Get default eValue.
                        eValue = eAttrType.getDefaultValue();
                        if (eValue != null) {
                            System.out.println("Default value : " + eValue.toString());
                        } else {
                            System.out.println("No value and no default value for " + key + " val:" + val);
                            // Render if its a number or if its a String.
                            Optional<Number> optNum = EntityManager.getAttrValueNumber(entity, key, val);
                            if (optNum.isPresent()) {
                                attributes.put(key, optNum.get());
                            } else {
                                attributes.put(key, val);
                            }
                            continue;
                        }
                    }
                    attributes.put(key, eValue);

                }
            }
        }

        return attributes;
    }

Helper methods to get eAttributeType :

/**
     * Return an ecore type from attribute name and entity object.
     *
     * @param entity
     * @param attrName
     * @return
     */
    public static Optional<EDataType> getEAttributeType(Entity entity, String attrName) {
        EDataType eDataType = null;
        String eAttributeName = Occi2Ecore.convertOcciAttributeName2EcoreAttributeName(attrName);
        final EStructuralFeature eStructuralFeature = entity.eClass().getEStructuralFeature(eAttributeName);
        if (eStructuralFeature != null) {
            if ((eStructuralFeature instanceof EAttribute)) {
                // Obtain the attribute type.
                eDataType = ((EAttribute) eStructuralFeature).getEAttributeType();
            }
        }
        return Optional.ofNullable(eDataType);
    }

To get attribute object value :

/**
     * @param entity
     * @param attrName
     * @return an object container value from EMF attribute object.
     */
    public static Optional<Object> getEMFValueObject(Entity entity, String attrName) {
        EAttribute eAttr;
        Object result = null;
        String eAttributeName = Occi2Ecore.convertOcciAttributeName2EcoreAttributeName(attrName);
        final EStructuralFeature eStructuralFeature = entity.eClass().getEStructuralFeature(eAttributeName);
        if (eStructuralFeature != null) {
            if ((eStructuralFeature instanceof EAttribute)) {
                eAttr = (EAttribute) eStructuralFeature;
                result = entity.eGet(eAttr);
            }
        }
        return Optional.ofNullable(result);
    }

I'm lost here, so my main question how to manage (set and get) complex datatypes and value objects programmatically ?