001    package org.andromda.core.metafacade;
002    
003    import java.io.Serializable;
004    import java.util.List;
005    import org.andromda.core.common.ClassUtils;
006    import org.andromda.core.common.ExceptionUtils;
007    import org.apache.commons.lang.StringUtils;
008    
009    /**
010     * Stores the validation messages that are collected during model validation.
011     *
012     * @author Chad Brandon
013     */
014    public class ModelValidationMessage
015        implements Serializable
016    {
017        private static final long serialVersionUID = 34L;
018    
019        /**
020         * Constructs a new instance of MetafacadeValidationMessage taking a
021         * <code>metafacade</code> instance and a <code>message</code>
022         * indicating what has been violated.
023         *
024         * @param metafacade the metafacade being validated.
025         * @param message the message to to communicate about the validation.
026         */
027        public ModelValidationMessage(
028            final MetafacadeBase metafacade,
029            final String message)
030        {
031            this(metafacade, null, message);
032        }
033    
034        /**
035         * Constructs a new instance of MetafacadeValidationMessage taking a
036         * <code>metafacade</code> instance the <code>name</code> of the
037         * validation constraint and the actual <code>message</code> text indicating
038         * what has been violated.
039         *
040         * @param metafacade the metafacade being validated.
041         * @param name the name of the model element being validated.
042         * @param message the message to communicate about the validation.
043         */
044        public ModelValidationMessage(
045            final MetafacadeBase metafacade,
046            final String name,
047            final String message)
048        {
049            ExceptionUtils.checkNull("metafacade", metafacade);
050            ExceptionUtils.checkEmpty("message", message);
051            this.metafacade = metafacade;
052            this.name = name;
053            this.message = message;
054        }
055    
056        /**
057         * Stores the actual name of the constraint (if there is one).
058         */
059        private String name;
060    
061        /**
062         * Gets the name of the validation constraint.
063         *
064         * @return the constraint name.
065         */
066        public String getName()
067        {
068            return this.name;
069        }
070    
071        /**
072         * Stores the actual message text.
073         */
074        private String message;
075    
076        /**
077         * Gets the actual message text.
078         *
079         * @return Returns the message.
080         */
081        public String getMessage()
082        {
083            return message;
084        }
085    
086        /**
087         * Stores the actual metafacade to which this validation message applies.
088         */
089        private MetafacadeBase metafacade;
090    
091        /**
092         * Stores the metafacade name which is only constructed the very first time.
093         */
094        private String metafacadeName = null;
095    
096        /**
097         * Gets the name of the metafacade to which this validation message applies.
098         *
099         * @return Returns the metafacade.
100         */
101        public String getMetafacadeName()
102        {
103            if (this.metafacadeName == null)
104            {
105                final String separator = MetafacadeConstants.NAMESPACE_SCOPE_OPERATOR;
106                final StringBuilder name = new StringBuilder();
107                for (
108                    MetafacadeBase metafacade = this.metafacade; metafacade != null;
109                    metafacade = (MetafacadeBase)metafacade.getValidationOwner())
110                {
111                    if (StringUtils.isNotBlank(metafacade.getValidationName()))
112                    {
113                        String validationName = metafacade.getValidationName();
114                        if (metafacade.getValidationOwner() != null)
115                        {
116                            // remove package if we have an owner
117                            validationName = validationName.replaceAll(".*" + separator, "");
118                        }
119                        if (name.length()>0)
120                        {
121                            name.insert(0, separator);
122                        }
123                        name.insert(0, validationName);
124                    }
125                }
126                this.metafacadeName = name.toString();
127            }
128            return metafacadeName;
129        }
130    
131        /**
132         * Stores the metafacade class displayed within the message, this is only retrieved the very first time.
133         */
134        private Class metafacadeClass = null;
135    
136        /**
137         * Gets the class of the metafacade to which this validation message applies.
138         *
139         * @return the metafacade Class.
140         */
141        public Class getMetafacadeClass()
142        {
143            if (metafacadeClass == null)
144            {
145                this.metafacadeClass = this.metafacade.getClass();
146                final List interfaces = ClassUtils.getAllInterfaces(this.metafacade.getClass());
147                if (interfaces != null && !interfaces.isEmpty())
148                {
149                    this.metafacadeClass = (Class)interfaces.iterator().next();
150                }
151            }
152            return this.metafacadeClass;
153        }
154    
155        /**
156         * @see Object#toString()
157         */
158        public String toString()
159        {
160            final StringBuilder toString = new StringBuilder();
161            toString.append('[');
162            toString.append(this.getMetafacadeName());
163            toString.append(']');
164            toString.append(':');
165            toString.append(this.message);
166            return toString.toString();
167        }
168    
169        /**
170         * @see Object#hashCode()
171         */
172        public int hashCode()
173        {
174            return this.toString().hashCode();
175        }
176    
177        /**
178         * @see Object#equals(Object)
179         */
180        @SuppressWarnings("null")
181        public boolean equals(Object object)
182        {
183            boolean equals = object != null && ModelValidationMessage.class == object.getClass();
184            if (equals)
185            {
186                final ModelValidationMessage message = (ModelValidationMessage)object;
187                // message can never be null at this point, because object cannot be null, despite the compiler warning
188                equals = message.toString().equals(this.toString());
189            }
190            return equals;
191        }
192    }