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

net.sf.jcc.model.parser.uml2.ConnectorHandler Maven / Gradle / Ivy

package net.sf.jcc.model.parser.uml2;

import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;

import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.xml.namespace.QNameEditor;

import au.com.sparxsystems.AggregationType;
import au.com.sparxsystems.Association;
import au.com.sparxsystems.AssociationProperties;
import net.sf.jcc.model.parser.ElementHandler;
import net.sf.jcc.model.parser.ElementHandlerException;
import net.sf.jcc.model.parser.ParseContext;
import net.sf.jcc.model.parser.XMLParseContext;
import net.sf.jcc.model.parser.XMLParsedElement;

public class ConnectorHandler implements ElementHandler
{
    private static final String IDREF_PREFIX = "EAID_";
    private static final String STYLE_SOURCE_ATTRIBUTE_PREFIX = "LFSP={";
    private static final String STYLE_TARGET_ATTRIBUTE_PREFIX = "LFEP={";

    private String sourceClassId;
    private String sourceAttributeId;
    private String targetClassId;
    private String targetAttributeId;
    private String sourceAggregationType;
    private String targetAggregationType;
    private AssociationProperties properties;
    private Association sourceAssociation;
    private Association targetAssociation;

    private static final Logger log = LoggerFactory.getLogger(ConnectorHandler.class);

    private static enum PROPERTY_TYPE
    {
        value, idref, aggregation
    }

    private static enum ELEMENT_TYPE
    {
        style, source, target, type, properties, modifiers;

    }

	@Override
	public String getName()
	{
		return getClass().getSimpleName();
	}
	
	@Override
	public void handleElement(ParseContext parseContext)
			throws ElementHandlerException
	{
        sourceClassId = null;
        sourceAttributeId = null;
        targetClassId = null;
        targetAttributeId = null;
        sourceAssociation = new Association();
        targetAssociation = new Association();

        XMLParsedElement pElement = (XMLParsedElement)parseContext.getParsedElement();
        StartElement element = pElement.getElement();

        handleChildElements(element.getName(), ((XMLParseContext)parseContext).getEventReader());

        assignAssociationsToElement((ElementStore) parseContext.getInternalStore());
	}

    private void assignAssociationsToElement(ElementStore store)
    {
        String sourceModelElementId = sourceAttributeId != null ? sourceAttributeId : sourceClassId;
        ModelElement sourceModelElement = store.get(sourceModelElementId);
        sourceAssociation.setTargetClassId(targetClassId);
        sourceAssociation.setTargetAttributeId(targetAttributeId);
        sourceAssociation.setAggregrationType(sourceAggregationType == null ? null : AggregationType.fromValue(sourceAggregationType));
        sourceAssociation.setProperties(properties);
        if (sourceModelElement != null)
        {
            sourceModelElement.addAssocation(sourceAssociation);
        }

        String targetModelElementId = targetAttributeId != null ? targetAttributeId : targetClassId;
        targetAssociation.setTargetClassId(sourceClassId);
        targetAssociation.setTargetAttributeId(sourceAttributeId);
        targetAssociation.setAggregrationType(targetAggregationType == null ? null : AggregationType.fromValue(targetAggregationType));
        ModelElement targetModelElement = store.get(targetModelElementId);
        if (targetModelElement != null)
        {
            targetModelElement.addAssocation(targetAssociation);
        }
    }

    private void handleChildElements(QName parentName, XMLEventReader eventReader)
    {
        while (eventReader.hasNext())
        {
            try
            {
                XMLEvent event = eventReader.nextEvent();
                if (event.isStartElement())
                {
                    parseStyleToAssociation(event.asStartElement());
                    parseSourceElement(event.asStartElement());
                    parseTargetElement(event.asStartElement());
                    parseTypeElement(event.asStartElement(), parentName);
                    parseProperties(event.asStartElement());
                    parseModifiers(event.asStartElement(), parentName);

                    handleChildElements(event.asStartElement().getName(), eventReader);
                }
                else if (event.isEndElement())
                {
                    QName qName = event.asEndElement().getName();
                    if (qName.equals(parentName))
                    {
                        return;
                    }
                }
            }
            catch (XMLStreamException e)
            {
                e.printStackTrace();
            }
        }
    }

    private void parseProperties(StartElement element)
    {
        if (element == null || !ELEMENT_TYPE.properties.toString().equals(element.getName().toString()))
        {
            return;
        }

        properties = new AssociationProperties();
        assignProperties(properties, element.asStartElement());
    }

    private void parseModifiers(StartElement element, QName parentName)
    {
        if (element == null || !ELEMENT_TYPE.modifiers.toString().equals(element.getName().toString()))
        {
            return;
        }

        if (ELEMENT_TYPE.source.toString().equals(parentName.toString()))
        {
            assignProperties(sourceAssociation, element.asStartElement());
        }
        else if (ELEMENT_TYPE.target.toString().equals(parentName.toString()))
        {
            assignProperties(targetAssociation, element.asStartElement());
        }
    }

    private void parseStyleToAssociation(StartElement element)
    {
        if (element == null || !ELEMENT_TYPE.style.toString().equals(element.getName().toString()))
        {
            return;
        }

        Attribute attr = element.getAttributeByName(new QName("", PROPERTY_TYPE.value.toString()));
        String value = attr == null ? null : attr.getValue();
        String targetModelGuid = extractTargetModelGuid(value);
        String targetAttributeIdRef = transformModelGuidToIdRef(targetModelGuid);

        String sourceModelGuid = extractSourceModelGuid(value);
        String sourceAttributeIdRef = transformModelGuidToIdRef(sourceModelGuid);

        if (targetAttributeIdRef != null)
        {
            targetAttributeId = targetAttributeIdRef;
        }
        if (sourceAttributeIdRef != null)
        {
            sourceAttributeId = sourceAttributeIdRef;
        }
    }

    private void parseSourceElement(StartElement element)
    {
        if (element != null && ELEMENT_TYPE.source.toString().equals(element.getName().toString()))
        {
            sourceClassId = getIdrefAttributeValue(element);
        }
    }

    private void parseTargetElement(StartElement element)
    {
        if (element != null && ELEMENT_TYPE.target.toString().equals(element.getName().toString()))
        {
            targetClassId = getIdrefAttributeValue(element);
        }
    }

    private void parseTypeElement(StartElement element, QName parentName)
    {
        if (element != null && ELEMENT_TYPE.type.toString().equals(element.getName().toString()))
        {
            if (ELEMENT_TYPE.source.toString().equals(parentName.toString()))
            {
                sourceAggregationType = getAggregationValue(element);
            }
            else if (ELEMENT_TYPE.target.toString().equals(parentName.toString()))
            {
                targetAggregationType = getAggregationValue(element);
            }

        }
    }

    private String getIdrefAttributeValue(StartElement element)
    {
        Attribute attr = element.getAttributeByName(new QName("http://schema.omg.org/spec/XMI/2.1", PROPERTY_TYPE.idref.toString()));
        return attr.getValue();
    }

    private String getAggregationValue(StartElement element)
    {
        Attribute attr = element.getAttributeByName(new QName(PROPERTY_TYPE.aggregation.toString()));
        return attr.getValue();
    }

    protected String extractTargetModelGuid(String styleString)
    {
        String targetModelGuid = StringUtils.substringBetween(styleString, STYLE_TARGET_ATTRIBUTE_PREFIX, "}");
        return targetModelGuid;
    }

    protected String extractSourceModelGuid(String styleString)
    {
        String sourceModelGuid = StringUtils.substringBetween(styleString, STYLE_SOURCE_ATTRIBUTE_PREFIX, "}");
        return sourceModelGuid;
    }

    protected String transformModelGuidToIdRef(String modelGuid)
    {
        if (modelGuid == null || "".equals(modelGuid))
            return null;

        String idRef = IDREF_PREFIX;
        return idRef.concat(StringUtils.replace(modelGuid, "-", "_"));
    }

    private static String[] ignore = {"ea_type", "isOrdered", "changeable"};

    private void assignProperties(Object e, StartElement element)
    {
        BeanWrapper wrapper = new BeanWrapperImpl(e);
        wrapper.registerCustomEditor(QName.class, new QNameEditor());

        for (Iterator itr = element.getAttributes(); itr.hasNext();)
        {
            Attribute attribute = itr.next();
            String name = attribute.getName().getLocalPart();
            if (ArrayUtils.contains(ignore, name))
            {
                continue;
            }

            Object value =  attribute.getValue();

            Class attributeClass = BeanUtils.findPropertyType(name, new Class[]{e.getClass()});
            if (attributeClass.isEnum())
            {
                Method method = BeanUtils.findDeclaredMethodWithMinimalParameters(attributeClass, "fromValue");
                try
                {
                    value = method.invoke(null, value);
                }
                catch (IllegalArgumentException e1)
                {
                    log.error("IllegalArgumentException trying to invoke fromValue");
                    return;
                }
                catch (IllegalAccessException e1)
                {
                    log.error("IllegalAccessException trying to invoke fromValue");
                    return;
                }
                catch (InvocationTargetException e1)
                {
                    log.error("InvocationTargetException trying to invoke fromValue");
                    return;
                }
            }
            PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(e.getClass(), name);
            if (pd == null)
            {
                PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(e.getClass());
                for (PropertyDescriptor pd1 : pds)
                {
                    if (pd1.getName().equalsIgnoreCase(name))
                    {
                        name = pd1.getDisplayName();
                        break;
                    }
                }
            }

            try
            {
                wrapper.setPropertyValue(name, value);
            }
            catch (Exception ex)
            {
                log.info("Error writing property value:" + name + " " + e.getClass().getName());
            }
        }
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy