001package org.andromda.core.metafacade; 002 003import java.io.Serializable; 004import java.util.List; 005import org.andromda.core.common.ClassUtils; 006import org.andromda.core.common.ExceptionUtils; 007import org.apache.commons.lang.StringUtils; 008 009/** 010 * Stores the validation messages that are collected during model validation. 011 * 012 * @author Chad Brandon 013 */ 014public 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") // Compiler doesn't not recognize that object cannot be null when using message 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 if (message != null) 189 { 190 equals = message.toString().equals(this.toString()); 191 } 192 } 193 return equals; 194 } 195}