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

org.nuiton.eugene.models.extension.io.ModelExtensionReader Maven / Gradle / Ivy

The newest version!
package org.nuiton.eugene.models.extension.io;

/*-
 * #%L
 * EUGene :: EUGene
 * %%
 * Copyright (C) 2004 - 2017 Code Lutin
 * %%
 * 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 Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.eugene.EugeneCoreTagValues;
import org.nuiton.eugene.models.extension.tagvalue.InvalidStereotypeSyntaxException;
import org.nuiton.eugene.models.extension.tagvalue.InvalidTagValueSyntaxException;
import org.nuiton.eugene.models.extension.tagvalue.MismatchTagValueTargetException;
import org.nuiton.eugene.models.extension.tagvalue.TagValueMetadata;
import org.nuiton.eugene.models.extension.tagvalue.TagValueNotFoundException;
import org.nuiton.eugene.models.extension.tagvalue.provider.AggregateTagValueMetadatasProvider;
import org.nuiton.eugene.models.extension.tagvalue.provider.TagValueMetadatasProvider;
import org.nuiton.eugene.models.object.ObjectModel;
import org.nuiton.eugene.models.object.ObjectModelAssociationClass;
import org.nuiton.eugene.models.object.ObjectModelAttribute;
import org.nuiton.eugene.models.object.ObjectModelClass;
import org.nuiton.eugene.models.object.ObjectModelClassifier;
import org.nuiton.eugene.models.object.ObjectModelPackage;
import org.nuiton.eugene.models.object.xml.ObjectModelAssociationClassImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelClassifierImpl;
import org.nuiton.eugene.models.object.xml.ObjectModelImpl;

import java.io.File;
import java.io.IOException;


/**
 * Created on 09/09/16.
 *
 * @author Tony Chemit - [email protected]
 * @since 3.0
 */
public class ModelExtensionReader implements ModelExtensionFileParserCallback {

    /** Logger. */
    private static final Log log = LogFactory.getLog(ModelExtensionReader.class);

    protected final boolean verbose;
    protected final boolean strictLoading;
    protected final M model;
    protected final TagValueMetadatasProvider tagValueMetadatasProvider;

    public ModelExtensionReader(boolean verbose, boolean strictLoading, M model) {
        this.verbose = verbose;
        this.strictLoading = strictLoading;
        this.model = model;
        this.tagValueMetadatasProvider = new AggregateTagValueMetadatasProvider(getClass().getClassLoader());
    }

    public void read(File modelExtension) throws IOException, InvalidTagValueSyntaxException, InvalidStereotypeSyntaxException {

        ModelExtensionFileParser parser = ModelExtensionFileParser.newParser(strictLoading, modelExtension);
        parser.parse(modelExtension, this);

    }

    @Override
    public boolean onModelTagValueFound(String tag, String value) {

        boolean safe = false;

        try {
            tagValueMetadatasProvider.validate(tag, ObjectModel.class);
            safe = true;
        } catch (TagValueNotFoundException e) {
            String message = "Invalid model tag value: the tagvalue '" + tag + "' is unknown.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        } catch (MismatchTagValueTargetException e) {
            String message = "Invalid model tag value: this tagvalue '" + tag + "' can not be apply on the model.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        }

        if (safe) {

            // test if tagValue is deprecated
            TagValueMetadata tagValueMetadata = tagValueMetadatasProvider.getTagValue(tag).get();
            boolean deprecated = tagValueMetadata.isDeprecated();
            if (deprecated) {
                if (log.isWarnEnabled()) {
                    log.warn("Deprecated tagValue usage: " + value);
                }
            }
        } else {
            if (strictLoading) {
                // in strict loading do not accept unsafe tags
                return false;
            }
        }

        ObjectModelImpl modelImpl = (ObjectModelImpl) model;
        if (tag.equals(EugeneCoreTagValues.Store.version.getName())) {

            // push directly the version in the model version property
            modelImpl.setVersion(value);
        }
        if (verbose) {
            log.info("model tag value imported " + tag + " → " + value);
        }
        modelImpl.addTagValue(tag, value);

        return safe;

    }

    @Override
    public boolean onModelStereotypeFound(String stereotype) {

        boolean safe = false;

        try {
            tagValueMetadatasProvider.validate(stereotype, ObjectModel.class);
            safe = true;
        } catch (TagValueNotFoundException e) {

            String message = "Invalid model stereotype [" + stereotype + "] : the stereotype '" + stereotype + "' is unknown.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        } catch (MismatchTagValueTargetException e) {
            String message = "Invalid model stereotype [" + stereotype + "] : this stereotype '" + stereotype + "' can not be apply on model.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        }

        if (safe) {

            // test if stereotype is deprecated
            TagValueMetadata tagValueMetadata = tagValueMetadatasProvider.getTagValue(stereotype).get();
            boolean deprecated = tagValueMetadata.isDeprecated();
            if (deprecated) {
                log.warn("Deprecated model stereotype usage: " + stereotype);
            }
        } else {
            if (strictLoading) {
                // in strict loading do not accept unsafe stereotypes
                return false;
            }
        }

        model.addTagValue(stereotype, "true");

        if (verbose) {
            log.info("stereotype imported " + stereotype + " → model.");
        }
        return safe;
    }

    @Override
    public boolean onPackageTagValueFound(String packageName, String tag, String value) {

        boolean safe = false;

        try {
            tagValueMetadatasProvider.validate(tag, ObjectModelPackage.class);
            safe = true;
        } catch (TagValueNotFoundException e) {
            String message = "Invalid tag value on package [" + packageName + "]: the tagvalue '" + tag + "' is unknown.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        } catch (MismatchTagValueTargetException e) {
            String message = "Invalid tag value on package [" + packageName + "]: this tagvalue '" + tag + "' can not be apply on the model.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }

        }

        if (safe) {

            // test if tagValue is deprecated
            TagValueMetadata tagValueMetadata = tagValueMetadatasProvider.getTagValue(tag).get();
            boolean deprecated = tagValueMetadata.isDeprecated();
            if (deprecated) {
                if (log.isWarnEnabled()) {
                    log.warn("Deprecated tagValue usage on package [" + packageName + "]: " + value);
                }
            }
        } else {
            if (strictLoading) {
                // in strict loading do not accept unsafe tags
                return false;
            }
        }

        ObjectModelPackage aPackage = model.getPackage(packageName);
        if (verbose) {
            log.info("imported tag value on package [" + packageName + "] → " + tag + " = " + value);
        }
        aPackage.addTagValue(tag, value);
        return true;
    }

    @Override
    public boolean onPackageStereotypeFound(String packageName, String stereotype) {

        boolean safe = false;
        try {
            tagValueMetadatasProvider.validate(stereotype, ObjectModelPackage.class);
            safe = true;
        } catch (TagValueNotFoundException e) {
            String message = "Invalid model stereotype on package [" + packageName + "]: the stereotype '" + stereotype + "' is unknown.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        } catch (MismatchTagValueTargetException e) {
            String message = "Invalid model stereotype on package [" + packageName + "]: this stereotype '" + stereotype + "' can not be apply on package.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        }

        if (safe) {

            // test if tagValue is deprecated
            TagValueMetadata tagValueMetadata = tagValueMetadatasProvider.getTagValue(stereotype).get();
            boolean deprecated = tagValueMetadata.isDeprecated();
            if (deprecated) {
                log.warn("Deprecated stereotype usage on package [" + packageName + "]: " + stereotype);
            }
        } else {
            if (strictLoading) {
                // in strict loading do not accept unsafe stereotypes
                return false;
            }
        }

        ObjectModelPackage omc = model.getPackage(packageName);
        if (omc == null) {

            // package not found
            return false;
        }

        omc.addTagValue(stereotype, "true");

        if (verbose) {
            log.info("imported stereotype on package [" + packageName + "] → " + stereotype);
        }

        return true;
    }

    @Override
    public boolean onClassTagValueFound(String className, String tag, String value) {

        boolean safe = false;

        try {
            tagValueMetadatasProvider.validate(tag, ObjectModelClass.class);
            safe = true;
        } catch (TagValueNotFoundException e) {

            String message = "Invalid tag value on class [" + className + "]: this tagvalue '" + tag + "' is unknown.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }

        } catch (MismatchTagValueTargetException e) {
            String message = "Invalid tag value on class [" + className + "]: this tagvalue '" + tag + "' can not be apply on class scope.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        }

        if (safe) {

            // test if tagValue is deprecated
            TagValueMetadata tagValueMetadata = tagValueMetadatasProvider.getTagValue(tag).get();
            boolean deprecated = tagValueMetadata.isDeprecated();
            if (deprecated) {
                if (log.isWarnEnabled()) {
                    log.warn("Deprecated tagValue usage on class [" + className + "] : " + value);
                }
            }
        } else {

            if (strictLoading) {
                // in strict loading do not accept unsafe tags
                return false;
            }
        }

        ObjectModelClassifier omc = getClassifier(className);
        if (omc == null) {

            // classifier not found
            return false;
        }

        omc.addTagValue(tag, value);

        if (verbose) {
            log.info("tag value imported on class [" + className + "] → " + tag + " = " + value);
        }
        return true;

    }

    @Override
    public boolean onClassStereotypeFound(String className, String stereotype) {

        boolean safe = false;
        try {
            tagValueMetadatasProvider.validate(stereotype, ObjectModelClassifier.class);
            safe = true;
        } catch (TagValueNotFoundException e) {

            String message = "Invalid model stereotype on class [" + className + "]: the stereotype '" + stereotype + "' is unknown.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        } catch (MismatchTagValueTargetException e) {
            String message = "Invalid model stereotype on class [" + className + "]: this stereotype '" + stereotype + "' can not be apply on class scope.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        }

        if (safe) {

            // test if stereotype is deprecated
            TagValueMetadata tagValueMetadata = tagValueMetadatasProvider.getTagValue(stereotype).get();
            boolean deprecated = tagValueMetadata.isDeprecated();
            if (deprecated) {
                if (log.isWarnEnabled()) {
                    log.warn("Deprecated stereotype usage on class [" + className + "]: " + stereotype);
                }
            }
        } else {
            if (strictLoading) {
                // in strict loading do not accept unsafe stereotypes
                return false;
            }
        }

        ObjectModelClassifier omc = getClassifier(className);
        if (omc == null) {

            // classifier not found
            return false;
        }

        omc.addTagValue(stereotype, "true");

        if (verbose) {
            log.info("stereotype imported on class [" + className + "] → " + stereotype);
        }

        return true;

    }

    @Override
    public boolean onAttributeTagValueFound(String className, String attributeName, String tag, String value) {

        boolean safe = false;

        try {
            tagValueMetadatasProvider.validate(tag, ObjectModelAttribute.class);
            safe = true;
        } catch (TagValueNotFoundException e) {

            String message = "Invalid tag value on attribute [" + className + "#" + attributeName + "]: this tagvalue '" + tag + "' is unknown.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }

        } catch (MismatchTagValueTargetException e) {
            String message = "Invalid tag value on attribute [" + className + "#" + attributeName + "]: this tagvalue '" + tag + "' can not be apply on attribute scope.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        }

        if (safe) {

            // test if tagValue is deprecated
            TagValueMetadata tagValueMetadata = tagValueMetadatasProvider.getTagValue(tag).get();
            boolean deprecated = tagValueMetadata.isDeprecated();
            if (deprecated) {
                if (log.isWarnEnabled()) {
                    log.warn("Deprecated tagValue usage on attribute [" + className + "#" + attributeName + "] : " + value);
                }
            }
        } else {

            if (strictLoading) {
                // in strict loading do not accept unsafe tags
                return false;
            }
        }

        ObjectModelClassifier omc = getClassifier(className);
        if (omc == null) {

            // classifier not found
            return false;
        }

        ObjectModelAttribute attribute = getAttribute(omc, attributeName);

        if (attribute == null) {

            // attribute not found
            return false;
        }
        attribute.addTagValue(tag, value);

        if (verbose) {
            log.info("tag value imported on attribute [" + className + "#" + attributeName + "] → " + tag + " = " + value);
        }
        return true;

    }

    @Override
    public boolean onAttributeStereotypeFound(String className, String attributeName, String stereotype) {

        boolean safe = false;
        try {
            tagValueMetadatasProvider.validate(stereotype, ObjectModelAttribute.class);
            safe = true;
        } catch (TagValueNotFoundException e) {

            String message = "Invalid model stereotype on attribute [" + className + "#" + attributeName + "]: the stereotype '" + stereotype + "' is unknown.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        } catch (MismatchTagValueTargetException e) {
            String message = "Invalid model stereotype on attribute [" + className + "#" + attributeName + "]: this stereotype '" + stereotype + "' can not be apply on attribute scope.";
            if (strictLoading) {
                log.error(message);
            } else {
                log.warn(message);
            }
        }

        if (safe) {

            // test if stereotype is deprecated
            TagValueMetadata tagValueMetadata = tagValueMetadatasProvider.getTagValue(stereotype).get();
            boolean deprecated = tagValueMetadata.isDeprecated();
            if (deprecated) {
                log.warn("Deprecated stereotype usage on attribute [" + className + "]: " + stereotype);
            }
        } else {
            if (strictLoading) {
                // in strict loading do not accept unsafe stereotypes
                return false;
            }
        }

        ObjectModelClassifier omc = getClassifier(className);
        if (omc == null) {

            // classifier not found
            return false;
        }
        ObjectModelAttribute attribute = getAttribute(omc, attributeName);
        if (attribute == null) {

            // attribute not found
            return false;
        }
        attribute.addStereotype(stereotype);

        if (verbose) {
            log.info("stereotype imported on attribute [" + className + "#" + attributeName + "] → " + stereotype);
        }

        return true;

    }


    protected ObjectModelClassifier getClassifier(String fqn) {
        ObjectModelClassifier omc = model.getClassifier(fqn);
        if (omc == null) {
            if (log.isWarnEnabled()) {
                log.warn("Could not find classifier for " + fqn);
            }
            return null;
        }

        //todo tchemit 2010-11-25 : what does it mean ? every thing extends ObjectModelClassifierImpl
        if (!(omc instanceof ObjectModelClassifierImpl)) {
            // TODO il faudra avoir des methodes d'acces en Set sur l'interface pour eviter ce message
            if (log.isWarnEnabled()) {
                log.warn("Can't add properties to model, " +
                                 "it's not an " +
                                 "ObjectModelClassifierImpl : " +
                                 omc.getQualifiedName());
            }
            return null;
        }
        return omc;
    }

    /**
     * Retrieve an attribute from a {@code clazz} with its {@code name}.
     * This method manage the association class case to explore participants
     * attributes if needed.
     *
     * @param clazz where the attribute need to be find
     * @param name  attribute name to find
     * @return the attribute found or null
     */
    protected ObjectModelAttribute getAttribute(ObjectModelClassifier clazz, String name) {
        ObjectModelAttribute result = clazz.getAttribute(name);

        // Ano #619 : FD-2010-05-17 : Specific case for Association class :
        // check on participant attributes
        if (result == null && clazz instanceof ObjectModelAssociationClassImpl) {
            if (log.isDebugEnabled()) {
                log.debug("Attribute " + name + " not found from " + clazz.getQualifiedName() + " association class. Will check participants...");
            }
            ObjectModelAssociationClass assoc = (ObjectModelAssociationClass) clazz;
            for (ObjectModelAttribute participant : assoc.getParticipantsAttributes()) {
                if (participant.getName().equals(name)) {
                    result = participant;
                    break;
                }
            }
        }
        return result;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy