001package org.andromda.cartridges.spring.metafacades; 002 003import java.util.Arrays; 004import java.util.Collection; 005import java.util.Iterator; 006import org.andromda.cartridges.spring.SpringProfile; 007import org.andromda.cartridges.spring.SpringUtils; 008import org.andromda.metafacades.uml.AttributeFacade; 009import org.andromda.metafacades.uml.ClassifierFacade; 010import org.andromda.metafacades.uml.ModelElementFacade; 011import org.andromda.metafacades.uml.ParameterFacade; 012import org.andromda.metafacades.uml.UMLProfile; 013import org.apache.commons.lang.StringUtils; 014 015/** 016 * MetafacadeLogic implementation for org.andromda.cartridges.spring.metafacades.SpringQueryOperation. 017 * 018 * @see org.andromda.cartridges.spring.metafacades.SpringQueryOperation 019 */ 020public class SpringQueryOperationLogicImpl 021 extends SpringQueryOperationLogic 022{ 023 private static final long serialVersionUID = 34L; 024 /** 025 * Public constructor for SpringQueryOperationLogicImpl 026 * @param metaObject 027 * @param context 028 * @see org.andromda.cartridges.spring.metafacades.SpringQueryOperation 029 */ 030 public SpringQueryOperationLogicImpl(Object metaObject, String context) 031 { 032 super(metaObject, context); 033 } 034 035 /** 036 * @return getQuery((SpringEntity)null) 037 * @see org.andromda.cartridges.spring.metafacades.SpringQueryOperationLogic#getQuery() 038 */ 039 protected String handleGetQuery() 040 { 041 return this.getQuery((SpringEntity)null); 042 } 043 044 /** 045 * Stores the translated query so that its only translated once. 046 */ 047 private String translatedQuery = null; 048 049 /** 050 * Retrieves the translated query. 051 */ 052 private String getTranslatedQuery() 053 { 054 if (this.translatedQuery == null) 055 { 056 this.translatedQuery = super.getQuery("query.Hibernate-QL"); 057 } 058 return this.translatedQuery; 059 } 060 061 /** 062 * Stores whether or not named parameters should be used in hibernate queries. 063 */ 064 private static final String USE_NAMED_PARAMETERS = "hibernateQueryUseNamedParameters"; 065 066 /** 067 * @return SpringMetafacadeUtils.getUseNamedParameters(this, useNamedParameters) 068 * @see org.andromda.cartridges.spring.metafacades.SpringQueryOperationLogic#isUseNamedParameters() 069 */ 070 protected boolean handleIsUseNamedParameters() 071 { 072 boolean useNamedParameters = Boolean.valueOf(String.valueOf(this.getConfiguredProperty(USE_NAMED_PARAMETERS))) 073 .booleanValue() 074 || StringUtils.isNotBlank(this.getTranslatedQuery()); 075 076 return SpringMetafacadeUtils.getUseNamedParameters(this, useNamedParameters); 077 } 078 079 /** 080 * @return getCriteriaArgument() != null 081 * @see org.andromda.cartridges.spring.metafacades.SpringQueryOperation#isCriteriaFinder() 082 */ 083 protected boolean handleIsCriteriaFinder() 084 { 085 return this.getCriteriaArgument() != null; 086 } 087 088 /** 089 * @return Parameter with UMLProfile.STEREOTYPE_CRITERIA 090 * @see org.andromda.cartridges.spring.metafacades.SpringQueryOperation#getCriteriaArgument() 091 */ 092 protected ParameterFacade handleGetCriteriaArgument() 093 { 094 ParameterFacade foundParameter = null; 095 for (final ParameterFacade parameter : this.getParameters()) 096 { 097 final ClassifierFacade type = parameter.getType(); 098 if (type != null && type.hasStereotype(UMLProfile.STEREOTYPE_CRITERIA)) 099 { 100 foundParameter = parameter; 101 break; 102 } 103 } 104 return foundParameter; 105 } 106 107 /** 108 * @param entity 109 * @return query 110 * @see org.andromda.cartridges.spring.metafacades.SpringQueryOperation#getQuery(org.andromda.cartridges.spring.metafacades.SpringEntity) 111 */ 112 protected String handleGetQuery(SpringEntity entity) 113 { 114 // first see if we can retrieve the query from the super class as an OCL 115 // translation 116 String queryString = this.getTranslatedQuery(); 117 118 // otherwise see if there is a query stored as a tagged value 119 if (StringUtils.isBlank(queryString)) 120 { 121 Object value = this.findTaggedValue(SpringProfile.TAGGEDVALUE_HIBERNATE_QUERY); 122 queryString = (String)value; 123 if (queryString != null) 124 { 125 // remove any excess whitespace 126 queryString = queryString.replaceAll("[$\\s]+", " "); 127 } 128 } 129 130 // if there wasn't any stored query, create one by default. 131 if (StringUtils.isBlank(queryString)) 132 { 133 ModelElementFacade owner = null; 134 String entityName = null; 135 if (entity == null) 136 { 137 owner = this.getOwner(); 138 entityName = owner.getFullyQualifiedName(); 139 } 140 else 141 { 142 owner = entity; 143 //retrieve the entity implementation for proper hibernate mapping resolving 144 entityName = entity.getFullyQualifiedEntityImplementationName(); 145 } 146 String variableName = StringUtils.uncapitalize(owner.getName()); 147 queryString = "from " + entityName + " as " + variableName; 148 if (!this.getArguments().isEmpty()) 149 { 150 queryString += " where"; 151 Collection<ParameterFacade> arguments = this.getArguments(); 152 Iterator<ParameterFacade> iterator = arguments.iterator(); 153 while(iterator.hasNext()) 154 { 155 final ParameterFacade argument = iterator.next(); 156 final ClassifierFacade type = argument.getType(); 157 if (type != null) 158 { 159 final String parameterName = argument.getName(); 160 if (type.isEmbeddedValue()) 161 { 162 for (final Iterator<AttributeFacade> attributeIterator = type.getAttributes(true).iterator(); attributeIterator.hasNext();) 163 { 164 final AttributeFacade attribute = attributeIterator.next(); 165 String parameter = "?"; 166 if (this.isUseNamedParameters()) 167 { 168 parameter = ':' + SpringUtils.concatNamesCamelCase(Arrays.asList(parameterName, attribute.getName())); 169 } 170 queryString += ' ' + variableName + '.' + parameterName + '.' + attribute.getName() + " = " + parameter; 171 if (attributeIterator.hasNext()) 172 { 173 queryString += " and"; 174 } 175 } 176 } 177 else 178 { 179 String parameter = "?"; 180 if (this.isUseNamedParameters()) 181 { 182 parameter = ':' + parameterName; 183 } 184 queryString += ' ' + variableName + '.' + parameterName + " = " + parameter; 185 if (iterator.hasNext()) 186 { 187 queryString += " and"; 188 } 189 } 190 } 191 } 192 } 193 } 194 return queryString; 195 } 196}