org.alfresco.web.bean.generator.BaseComponentGenerator.java Source code

Java tutorial

Introduction

Here is the source code for org.alfresco.web.bean.generator.BaseComponentGenerator.java

Source

/*
 * #%L
 * Alfresco Repository WAR Community
 * %%
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 * %%
 * This file is part of the Alfresco software. 
 * If the software was purchased under a paid Alfresco license, the terms of 
 * the paid license agreement will prevail.  Otherwise, the software is 
 * provided under the following open source license terms:
 * 
 * Alfresco 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.
 * 
 * Alfresco 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 * #L%
 */
package org.alfresco.web.bean.generator;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import javax.faces.FacesException;
import javax.faces.component.UIComponent;
import javax.faces.component.UIGraphic;
import javax.faces.component.UIOutput;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.el.ValueBinding;

import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
import org.alfresco.repo.dictionary.constraint.NumericRangeConstraint;
import org.alfresco.repo.dictionary.constraint.RegexConstraint;
import org.alfresco.repo.dictionary.constraint.StringLengthConstraint;
import org.alfresco.service.cmr.dictionary.AssociationDefinition;
import org.alfresco.service.cmr.dictionary.Constraint;
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.namespace.QName;
import org.alfresco.web.app.Application;
import org.alfresco.web.app.servlet.FacesHelper;
import org.alfresco.web.bean.repository.DataDictionary;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.ui.common.ComponentConstants;
import org.alfresco.web.ui.repo.RepoConstants;
import org.alfresco.web.ui.repo.component.UIMultiValueEditor;
import org.alfresco.web.ui.repo.component.property.BaseAssociationEditor;
import org.alfresco.web.ui.repo.component.property.PropertySheetItem;
import org.alfresco.web.ui.repo.component.property.UIProperty;
import org.alfresco.web.ui.repo.component.property.UIPropertySheet;
import org.alfresco.web.ui.repo.component.property.UISeparator;
import org.alfresco.web.ui.repo.component.property.UIPropertySheet.ClientValidation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.jsf.FacesContextUtils;

public abstract class BaseComponentGenerator implements IComponentGenerator {
    private static Log logger = LogFactory.getLog(BaseComponentGenerator.class);

    protected enum ControlType {
        FIELD, SELECTOR;
    }

    protected DataDictionary dataDictionary;

    @SuppressWarnings("unchecked")
    public UIComponent generateAndAdd(FacesContext context, UIPropertySheet propertySheet, PropertySheetItem item) {
        UIComponent component = null;

        if (item instanceof UIProperty) {
            // get the property definition
            PropertyDefinition propertyDef = getPropertyDefinition(context, propertySheet.getNode(),
                    item.getName());

            // create the component and add it to the property sheet
            component = createComponent(context, propertySheet, item);

            // setup the component for multi value editing if necessary
            component = setupMultiValuePropertyIfNecessary(context, propertySheet, item, propertyDef, component);

            // setup common aspects of the property i.e. value binding
            setupProperty(context, propertySheet, item, propertyDef, component);

            // add the component now, it needs to be added before the validations
            // are setup as we need access to the component id, which in turn needs 
            // to have a parent to get the correct id
            item.getChildren().add(component);

            // setup the component for mandatory validation if necessary
            setupMandatoryPropertyIfNecessary(context, propertySheet, item, propertyDef, component);

            // setup any constraints the property has
            setupConstraints(context, propertySheet, item, propertyDef, component);

            // setup any converter the property needs
            setupConverter(context, propertySheet, item, propertyDef, component);
        } else if (item instanceof UISeparator) {
            // just create the component and add it
            component = createComponent(context, propertySheet, item);
            item.getChildren().add(component);
        } else {
            // get the association definition
            AssociationDefinition assocationDef = this.getAssociationDefinition(context, propertySheet.getNode(),
                    item.getName());

            // create the component and add it to the property sheet
            component = createComponent(context, propertySheet, item);

            // setup common aspects of the association i.e. value binding
            setupAssociation(context, propertySheet, item, assocationDef, component);

            // add the component now, it needs to be added before the validations
            // are setup as we need access to the component id, which needs have a
            // parent to get the correct id
            item.getChildren().add(component);

            // setup the component for mandatory validation if necessary
            setupMandatoryAssociationIfNecessary(context, propertySheet, item, assocationDef, component);

            // setup any converter the association needs
            setupConverter(context, propertySheet, item, assocationDef, component);
        }

        return component;
    }

    /**
     * Creates the component for the given proerty sheet item.
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet being generated
     * @param item The property or association being generated
     * @return The newly created component
     */
    @SuppressWarnings("unchecked")
    protected UIComponent createComponent(FacesContext context, UIPropertySheet propertySheet,
            PropertySheetItem item) {
        UIComponent component = null;

        if (item instanceof UIProperty) {
            if (propertySheet.inEditMode()) {
                // use the standard component in edit mode
                component = generate(context, item.getName());
            } else {
                // create an output text component in view mode
                component = createOutputTextComponent(context, item.getName());
            }
        } else {
            // create the standard association component
            component = generate(context, item.getName());
        }

        return component;
    }

    /**
     * Creates the converter with the given id and adds it to the component.
     * 
     * @param context FacesContext
     * @param converterId The name of the converter to create
     * @param component The component to add the converter to
     */
    protected void createAndSetConverter(FacesContext context, String converterId, UIComponent component) {
        if (converterId != null && component instanceof UIOutput) {
            try {
                Converter conv = context.getApplication().createConverter(converterId);
                ((UIOutput) component).setConverter(conv);
            } catch (NullPointerException npe) {
                // workaround a NPE bug in MyFaces
                logger.warn("Converter " + converterId + " could not be applied");
            } catch (FacesException fe) {
                logger.warn("Converter " + converterId + " could not be applied");
            }
        }
    }

    /**
     * Creates an output text component.
     * 
     * @param context FacesContext
     * @param id Optional id to set
     * @return The new component
     */
    protected UIOutput createOutputTextComponent(FacesContext context, String id) {
        UIOutput component = (UIOutput) context.getApplication()
                .createComponent(ComponentConstants.JAVAX_FACES_OUTPUT);

        component.setRendererType(ComponentConstants.JAVAX_FACES_TEXT);
        FacesHelper.setupComponentId(context, component, id);

        return component;
    }

    /**
     * Sets up the property component i.e. setting the value binding
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet
     * @param item The parent component
     * @param propertyDef The property definition
     * @param component The component representing the property
     */
    @SuppressWarnings("unchecked")
    protected void setupProperty(FacesContext context, UIPropertySheet propertySheet, PropertySheetItem item,
            PropertyDefinition propertyDef, UIComponent component) {
        // create and set the value binding
        ValueBinding vb = null;

        if (propertyDef != null) {
            vb = context.getApplication().createValueBinding(
                    "#{" + propertySheet.getVar() + ".properties[\"" + propertyDef.getName().toString() + "\"]}");
        } else {
            vb = context.getApplication()
                    .createValueBinding("#{" + propertySheet.getVar() + ".properties[\"" + item.getName() + "\"]}");
        }

        component.setValueBinding("value", vb);

        // disable the component if it is read only or protected
        // or if the property sheet is in view mode
        if (propertySheet.inEditMode() == false || item.isReadOnly()
                || (propertyDef != null && propertyDef.isProtected())) {
            component.getAttributes().put("disabled", Boolean.TRUE);
        }
    }

    /**
     * Sets up the association component i.e. setting the value binding
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet
     * @param item The parent component
     * @param associationDef The association definition
     * @param component The component representing the association
     */
    @SuppressWarnings("unchecked")
    protected void setupAssociation(FacesContext context, UIPropertySheet propertySheet, PropertySheetItem item,
            AssociationDefinition associationDef, UIComponent component) {
        // create and set the value binding
        ValueBinding vb = context.getApplication().createValueBinding("#{" + propertySheet.getVar() + "}");
        component.setValueBinding("value", vb);

        // set the association name and set to disabled if appropriate
        ((BaseAssociationEditor) component).setAssociationName(associationDef.getName().toString());

        // disable the component if it is read only or protected
        // or if the property sheet is in view mode
        if (propertySheet.inEditMode() == false || item.isReadOnly()
                || (associationDef != null && associationDef.isProtected())) {
            component.getAttributes().put("disabled", Boolean.TRUE);
        }
    }

    /**
     * Creates a wrapper component around the given component to enable the user
     * to edit multiple values.
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet being generated
     * @param property The property being generated
     * @param propertyDef The data dictionary definition for the property
     * @param component The component representing the property
     * @return A wrapped component if the property is multi-valued or the 
     *         original component if it is not multi-valued
     */
    @SuppressWarnings("unchecked")
    protected UIComponent setupMultiValuePropertyIfNecessary(FacesContext context, UIPropertySheet propertySheet,
            PropertySheetItem property, PropertyDefinition propertyDef, UIComponent component) {
        UIComponent multiValueComponent = component;

        if (propertySheet.inEditMode() && property.isReadOnly() == false && propertyDef != null
                && propertyDef.isProtected() == false && propertyDef.isMultiValued()) {
            // if the property is multi-valued create a multi value editor wrapper component
            String id = "multi_" + property.getName();
            multiValueComponent = context.getApplication()
                    .createComponent(RepoConstants.ALFRESCO_FACES_MULTIVALUE_EDITOR);
            FacesHelper.setupComponentId(context, multiValueComponent, id);

            // set the renderer depending on whether the item is a 'field' or a 'selector'
            if (getControlType() == ControlType.FIELD) {
                multiValueComponent.setRendererType(RepoConstants.ALFRESCO_FACES_FIELD_RENDERER);

                // set flag to indicate the wrapped field is multilingual, if necessary
                if (propertyDef.getDataType().getName().equals(DataTypeDefinition.MLTEXT)) {
                    multiValueComponent.getAttributes().put("mltext", Boolean.TRUE);
                }
            } else {
                multiValueComponent.setRendererType(RepoConstants.ALFRESCO_FACES_SELECTOR_RENDERER);

                // set the value binding for the wrapped component and the lastItemAdded attribute of
                // the multi select component, needs to point somewhere that can hold any object, it
                // will store the item last added by the user.
                String expr = "#{MultiValueEditorBean.lastItemsAdded['" + property.getName() + "']}";
                ValueBinding vb = context.getApplication().createValueBinding(expr);
                multiValueComponent.setValueBinding("lastItemAdded", vb);
                component.setValueBinding("value", vb);
            }

            // add the original component as a child of the wrapper
            multiValueComponent.getChildren().add(component);
        }

        return multiValueComponent;
    }

    /**
     * Sets up a mandatory validation rule for the given property.
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet being generated
     * @param property The property being generated
     * @param propertyDef The data dictionary definition of the property
     * @param component The component representing the property
     */
    @SuppressWarnings("unchecked")
    protected void setupMandatoryPropertyIfNecessary(FacesContext context, UIPropertySheet propertySheet,
            PropertySheetItem property, PropertyDefinition propertyDef, UIComponent component) {
        // only setup validations if the property sheet is in edit mode,
        // validation is enabled and the property is declared as mandatory
        if (propertySheet.inEditMode() && propertySheet.isValidationEnabled() && propertyDef != null
                && propertyDef.isMandatory()) {
            setupMandatoryValidation(context, propertySheet, property, component, false, null);
            setupMandatoryMarker(context, property);
        }
    }

    /**
     * Sets up a mandatory validation rule for the given association.
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet being generated
     * @param association The association being generated
     * @param associationDef The data dictionary definition of the association
     * @param component The component representing the association
     */
    protected void setupMandatoryAssociationIfNecessary(FacesContext context, UIPropertySheet propertySheet,
            PropertySheetItem association, AssociationDefinition associationDef, UIComponent component) {
        // only setup validations if the property sheet is in edit mode,
        // validation is enabled and the association is declared as mandatory
        if (propertySheet.inEditMode() && propertySheet.isValidationEnabled() && associationDef != null
                && associationDef.isTargetMandatory()) {
            setupMandatoryValidation(context, propertySheet, association, component, false, null);
            setupMandatoryMarker(context, association);
        }
    }

    /**
     * Sets up a client mandatory validation rule with the property
     * sheet for the given item.
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet to add the validation rule to
     * @param item The item being generated
     * @param component The component representing the item
     * @param realTimeChecking true to make the client validate as the user types
     * @param idSuffix An optional suffix to add to the client id
     */
    protected void setupMandatoryValidation(FacesContext context, UIPropertySheet propertySheet,
            PropertySheetItem item, UIComponent component, boolean realTimeChecking, String idSuffix) {
        List<String> params = new ArrayList<String>(3);

        // add the value parameter
        StringBuilder value = new StringBuilder("document.getElementById('");
        value.append(component.getClientId(context));
        if (idSuffix != null) {
            value.append(idSuffix);
        }
        value.append("')");
        params.add(value.toString());

        // add the validation failed message to show (use the value of the 
        // label component of the given item)
        String msg = Application.getMessage(context, "validation_mandatory");
        addStringConstraintParam(params,
                MessageFormat.format(msg, new Object[] { item.getResolvedDisplayLabel() }));

        // add the validation case to the property sheet
        propertySheet.addClientValidation(new ClientValidation("validateMandatory", params, realTimeChecking));
    }

    /**
     * Sets up the marker to show that the item is mandatory.
     * 
     * @param context FacesContext
     * @param item The item being generated
     */
    @SuppressWarnings("unchecked")
    protected void setupMandatoryMarker(FacesContext context, PropertySheetItem item) {
        // create the required field graphic
        UIGraphic image = (UIGraphic) context.getApplication().createComponent(UIGraphic.COMPONENT_TYPE);
        image.setUrl("/images/icons/required_field.gif");
        image.getAttributes().put("style", "padding-right: 4px;");

        // add marker as child to the property sheet item
        item.getChildren().add(image);
    }

    /**
     * Sets up client validation rules for any constraints the property has.
     * 
     * @param context FacesContext
     * propertySheet The property sheet being generated
     * @param property The property being generated
     * @param propertyDef The data dictionary definition of the property
     * @param component The component representing the property
     */
    protected void setupConstraints(FacesContext context, UIPropertySheet propertySheet, PropertySheetItem property,
            PropertyDefinition propertyDef, UIComponent component) {
        // only setup constraints if the property sheet is in edit mode,
        // validation is enabled
        if (propertySheet.inEditMode() && propertySheet.isValidationEnabled() && propertyDef != null) {
            List<ConstraintDefinition> constraints = propertyDef.getConstraints();
            for (ConstraintDefinition constraintDef : constraints) {
                Constraint constraint = constraintDef.getConstraint();

                if (constraint instanceof RegexConstraint) {
                    setupRegexConstraint(context, propertySheet, property, component, (RegexConstraint) constraint,
                            false);
                } else if (constraint instanceof StringLengthConstraint) {
                    setupStringLengthConstraint(context, propertySheet, property, component,
                            (StringLengthConstraint) constraint, false);
                } else if (constraint instanceof NumericRangeConstraint) {
                    setupNumericRangeConstraint(context, propertySheet, property, component,
                            (NumericRangeConstraint) constraint, false);
                } else if (constraint instanceof ListOfValuesConstraint) {
                    // NOTE: This is dealt with at the component creation stage
                    //       as a different component is usually required.
                }
            }
        }
    }

    /**
     * Sets up a default validation rule for the regular expression constraint
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet to add the validation rule to
     * @param property The property being generated
     * @param component The component representing the property
     * @param constraint The constraint to setup
     * @param realTimeChecking true to make the client validate as the user types
     */
    protected void setupRegexConstraint(FacesContext context, UIPropertySheet propertySheet,
            PropertySheetItem property, UIComponent component, RegexConstraint constraint,
            boolean realTimeChecking) {
        String expression = constraint.getExpression();
        boolean requiresMatch = constraint.getRequiresMatch();

        List<String> params = new ArrayList<String>(3);

        // add the value parameter
        String value = "document.getElementById('" + component.getClientId(context)
                + (component instanceof UIMultiValueEditor ? "_current_value" : "") + "')";
        params.add(value);

        // add the regular expression parameter
        try {
            // encode the expression so it can be unescaped by JavaScript
            addStringConstraintParam(params, URLEncoder.encode(expression, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            // just add the expression as is
            addStringConstraintParam(params, expression);
        }

        // add the requiresMatch parameter
        params.add(Boolean.toString(requiresMatch));

        // add the validation failed messages
        String matchMsg = Application.getMessage(context, "validation_regex");
        addStringConstraintParam(params,
                MessageFormat.format(matchMsg, new Object[] { property.getResolvedDisplayLabel() }));

        String noMatchMsg = Application.getMessage(context, "validation_regex_not_match");
        addStringConstraintParam(params,
                MessageFormat.format(noMatchMsg, new Object[] { property.getResolvedDisplayLabel() }));

        // add the validation case to the property sheet
        propertySheet.addClientValidation(new ClientValidation(
                (component instanceof UIMultiValueEditor ? "validateMultivalueRegex" : "validateRegex"), params,
                realTimeChecking));
    }

    /**
     * Sets up a default validation rule for the string length constraint
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet to add the validation rule to
     * @param property The property being generated
     * @param component The component representing the property
     * @param constraint The constraint to setup
     * @param realTimeChecking true to make the client validate as the user types
     */
    protected void setupStringLengthConstraint(FacesContext context, UIPropertySheet propertySheet,
            PropertySheetItem property, UIComponent component, StringLengthConstraint constraint,
            boolean realTimeChecking) {
        int min = constraint.getMinLength();
        int max = constraint.getMaxLength();

        List<String> params = new ArrayList<String>(3);

        // add the value parameter
        String value = "document.getElementById('" + component.getClientId(context) + "')";
        params.add(value);

        // add the min parameter
        params.add(Integer.toString(min));

        // add the max parameter
        params.add(Integer.toString(max));

        // add the validation failed message to show
        String msg = Application.getMessage(context, "validation_string_length");
        addStringConstraintParam(params,
                MessageFormat.format(msg, new Object[] { property.getResolvedDisplayLabel(), min, max }));

        // add the validation case to the property sheet
        propertySheet.addClientValidation(new ClientValidation("validateStringLength", params, realTimeChecking));
    }

    /**
     * Sets up a default validation rule for the numeric range constraint
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet to add the validation rule to
     * @param property The property being generated
     * @param component The component representing the property
     * @param constraint The constraint to setup
     * @param realTimeChecking true to make the client validate as the user types
     */
    protected void setupNumericRangeConstraint(FacesContext context, UIPropertySheet propertySheet,
            PropertySheetItem property, UIComponent component, NumericRangeConstraint constraint,
            boolean realTimeChecking) {
        double min = constraint.getMinValue();
        double max = constraint.getMaxValue();

        List<String> params = new ArrayList<String>(3);

        // add the value parameter
        String value = "document.getElementById('" + component.getClientId(context) + "')";
        params.add(value);

        // add the min parameter
        params.add(Double.toString(min));

        // add the max parameter
        params.add(Double.toString(max));

        // add the validation failed message to show
        String msg = Application.getMessage(context, "validation_numeric_range");
        addStringConstraintParam(params,
                MessageFormat.format(msg, new Object[] { property.getResolvedDisplayLabel(), min, max }));

        // add the validation case to the property sheet
        propertySheet.addClientValidation(new ClientValidation("validateNumberRange", params, false));
    }

    /**
     * Sets up the appropriate converter for the given property
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet being generated
     * @param property The property being generated
     * @param propertyDef The data dictionary definition of the property
     * @param component The component representing the property
     */
    protected void setupConverter(FacesContext context, UIPropertySheet propertySheet, PropertySheetItem property,
            PropertyDefinition propertyDef, UIComponent component) {
        if (property.getConverter() != null) {
            // create and add the custom converter
            createAndSetConverter(context, property.getConverter(), component);
        } else if (propertySheet.inEditMode() == false && propertyDef != null && propertyDef.isMultiValued()) {
            // if there isn't a custom converter and the property is
            // multi-valued add the multi value converter as a default
            createAndSetConverter(context, RepoConstants.ALFRESCO_FACES_MULTIVALUE_CONVERTER, component);
        }
    }

    /**
     * Sets up the appropriate converter for the given association
     * 
     * @param context FacesContext
     * @param propertySheet The property sheet being generated
     * @param association The association being generated
     * @param associationDef The data dictionary definition of the property
     * @param component The component representing the association
     */
    protected void setupConverter(FacesContext context, UIPropertySheet propertySheet,
            PropertySheetItem association, AssociationDefinition associationDef, UIComponent component) {
        if (association.getConverter() != null) {
            // create and add the custom converter
            createAndSetConverter(context, association.getConverter(), component);
        }
    }

    /**
     * Returns the type of the control being generated
     * 
     * @return The type of the control either a FIELD or a SELECTOR
     */
    protected ControlType getControlType() {
        return ControlType.FIELD;
    }

    /**
     * Retrieve the PropertyDefinition for the given property name on the given node
     * 
     * @param node The node to get the property definition from
     * @param propertyName The name of the property
     * @return PropertyDefinition for the node or null if a definition can not be found
     */
    protected PropertyDefinition getPropertyDefinition(FacesContext context, Node node, String propertyName) {
        return getDataDictionary(context).getPropertyDefinition(node, propertyName);
    }

    /**
     * Retrieve the AssociationDefinition for the given property name on the given node
     * 
     * @param node The node to get the association definition from
     * @param associationName The name of the property
     * @return AssociationDefinition for the node or null if a definition can not be found
     */
    protected AssociationDefinition getAssociationDefinition(FacesContext context, Node node,
            String associationName) {
        return getDataDictionary(context).getAssociationDefinition(node, associationName);
    }

    /**
     * Adds the given string parameter to the list of parameters to be used for
     * validating constraints on the client.
     * This method adds the quotes around the given parameter and also escapes
     * any ocurrences of the double quote character.
     * 
     * @param params The list of parameters for the constraint
     * @param param The string parameter to add
     */
    protected void addStringConstraintParam(List<String> params, String param) {
        params.add("\"" + StringUtils.replace(param, "\"", "\\\"") + "\"");
    }

    private DataDictionary getDataDictionary(FacesContext context) {
        if (this.dataDictionary == null) {
            this.dataDictionary = (DataDictionary) FacesContextUtils.getRequiredWebApplicationContext(context)
                    .getBean(Application.BEAN_DATA_DICTIONARY);
        }

        return this.dataDictionary;
    }

    public boolean isEnabledInEditMode(FacesContext context, UIComponent control, PropertyDefinition propDef) {
        // get type info for the property
        DataTypeDefinition dataTypeDef = propDef.getDataType();
        QName typeName = dataTypeDef.getName();
        if (typeName.equals(DataTypeDefinition.NODE_REF) || typeName.equals(DataTypeDefinition.PATH)
                || typeName.equals(DataTypeDefinition.CONTENT) || typeName.equals(DataTypeDefinition.QNAME)
                || typeName.equals(DataTypeDefinition.CHILD_ASSOC_REF)
                || typeName.equals(DataTypeDefinition.ASSOC_REF)) {
            return false;
        } else {
            return true;
        }
    }
}