View Javadoc

1   /*
2    * Copyright 2006-2010 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package net.sourceforge.domian.specification;
17  
18  
19  import java.util.Set;
20  
21  import org.apache.commons.lang.NotImplementedException;
22  import org.slf4j.Logger;
23  import org.slf4j.LoggerFactory;
24  
25  import net.sourceforge.domian.entity.Entity;
26  import static net.sourceforge.domian.specification.Specification2JpqlConverter.convertSetterOrGetterMethodName2FieldName;
27  
28  
29  /** HQL will be a fall-back from JPQL... */
30  public final class Specification2HqlConverter {
31  
32      private static final Logger log = LoggerFactory.getLogger(Specification2HqlConverter.class);
33  
34      /**
35       * An attempt to convert <b><i>Entity-type</i></b> Specification to polymorphic-friendly Hibernate Query language (HQL) query expression.
36       *
37       * @return an HQL query expression string
38       */
39      // TODO v0.5: move to Domian specification common representation - parse and build JPQL/HQL out of a structured string instead of this mess...
40      public static String convertSpecification2HqlQuery(final Specification<? extends Entity> specification) {
41          final StringBuilder hqlExpression = new StringBuilder("from java.lang.Object entity");
42          if (specification.getType().equals(Entity.class)) {
43              if (specification instanceof CompositeSpecification) {
44                  buildHqlFromEntityTypeCompositeSpecification((CompositeSpecification<Entity>) specification, hqlExpression);
45              }
46          } else {
47              log.warn("convertSpecification2HqlQuery() is only applicable for Specification<Entity> - returning '" + hqlExpression.toString() + "'");
48          }
49          return hqlExpression.toString();
50      }
51  
52  
53      private static void buildHqlFromEntityTypeCompositeSpecification(final CompositeSpecification<Entity> specification,
54                                                                       final StringBuilder hqlExpression) {
55          if (specification instanceof AbstractCompositeSpecification) {
56              AbstractCompositeSpecification abstractCompositeSpecification = (AbstractCompositeSpecification) specification;
57              if (!abstractCompositeSpecification.specifications.isEmpty()) {
58                  final Set<Specification<? super Entity>> specificationComposites = abstractCompositeSpecification.specifications;
59                  for (Specification<? super Entity> specificationComposite : specificationComposites) {
60                      if (specificationComposite instanceof CompositeSpecification) {
61                          if (!isTypeOnlyCompositeSpecification((CompositeSpecification<Entity>) specificationComposite)) {
62                              buildHqlFromEntityTypeCompositeSpecification((CompositeSpecification<Entity>) specificationComposite, hqlExpression);
63                          }
64  
65                      } else if (specificationComposite instanceof ParameterizedSpecification) {
66                          ParameterizedSpecification parameterizedSpecification = (ParameterizedSpecification) specificationComposite;
67                          if (parameterizedSpecification.accessibleObjectSpecification instanceof CompositeSpecification) {
68                              final String name;
69                              if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
70                                  name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
71                              } else {
72                                  name = parameterizedSpecification.getName();
73                              }
74                              hqlExpression.append(" where entity.");
75                              hqlExpression.append(name);
76  
77                              buildHqlFromCompositeSpecification((CompositeSpecification<?>) parameterizedSpecification.accessibleObjectSpecification,
78                                                                 parameterizedSpecification,
79                                                                 false,
80                                                                 hqlExpression);
81  
82                          } else if (parameterizedSpecification.accessibleObjectSpecification instanceof LeafSpecification) {
83                              LeafSpecification leafSpecification = (LeafSpecification) parameterizedSpecification.accessibleObjectSpecification;
84                              if (leafSpecification instanceof ValueBoundSpecification) {
85                                  if (leafSpecification instanceof EqualSpecification) {
86                                      ValueBoundSpecification valueBoundSpecification = (ValueBoundSpecification) leafSpecification;
87                                      final String name;
88                                      if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
89                                          name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
90                                      } else {
91                                          name = parameterizedSpecification.getName();
92                                      }
93                                      Object value = valueBoundSpecification.getValue();
94                                      hqlExpression.append(" where entity.");
95                                      hqlExpression.append(name);
96                                      hqlExpression.append(" = ");
97                                      hqlExpression.append(value);
98  
99                                  } else if (leafSpecification instanceof GreaterThanSpecification) {
100                                     ValueBoundSpecification valueBoundSpecification = (ValueBoundSpecification) leafSpecification;
101                                     final String name;
102                                     if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
103                                         name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
104                                     } else {
105                                         name = parameterizedSpecification.getName();
106                                     }
107                                     Object value = valueBoundSpecification.getValue();
108                                     hqlExpression.append(" where entity.");
109                                     hqlExpression.append(name);
110                                     hqlExpression.append(" > ");
111                                     hqlExpression.append(value);
112 
113                                 } else {
114                                     throw new NotImplementedException();
115                                 }
116 
117                             } else if (leafSpecification instanceof NotNullSpecification) {
118                                 final String name;
119                                 if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
120                                     name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
121                                 } else {
122                                     name = parameterizedSpecification.getName();
123                                 }
124                                 hqlExpression.append(" where entity.");
125                                 hqlExpression.append(name);
126                                 hqlExpression.append(" is not null");
127 
128                             } else if (leafSpecification instanceof DefaultValueSpecification) {
129                                 final String name;
130                                 if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
131                                     name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
132                                 } else {
133                                     name = parameterizedSpecification.getName();
134                                 }
135                                 hqlExpression.append(" where entity.");
136                                 hqlExpression.append(name);
137                                 //hqlExpression.append(" = ' '");
138                                 hqlExpression.append(" is null");
139 
140                             } else {
141                                 throw new NotImplementedException();
142                             }
143 
144                         } else {
145                             throw new NotImplementedException();
146                         }
147 
148                     } else if (specificationComposite instanceof LeafSpecification) {
149                         if (specificationComposite instanceof NotNullSpecification) {
150                             //hqlExpression.append(HQL_ALL_OBJECTS);
151                         } else {
152                             throw new NotImplementedException();
153                         }
154 
155                     } else {
156                         throw new NotImplementedException();
157                     }
158                 }
159             }
160 
161         } else {
162             log.warn("Specification is a " + CompositeSpecification.class.getName() +
163                      ", but is not extending " + AbstractCompositeSpecification.class.getName());
164         }
165     }
166 
167 
168     private static void buildHqlFromCompositeSpecification(final CompositeSpecification<?> compositeSpecification,
169                                                            final ParameterizedSpecification parentParameterizedSpecification,
170                                                            boolean negated,
171                                                            final StringBuilder hqlExpression) {
172         if (compositeSpecification instanceof AbstractCompositeSpecification) {
173             AbstractCompositeSpecification abstractCompositeSpecification = (AbstractCompositeSpecification) compositeSpecification;
174 
175             // TODO: må ta hensyn til type composite spec her gitt...
176             if (compositeSpecification instanceof JointDenialSpecification) {
177                 if (abstractCompositeSpecification.specifications.size() < 2) {
178                     negated = true;
179                 }
180             }
181 
182             if (!abstractCompositeSpecification.specifications.isEmpty()) {
183                 final Set<Specification<? super Entity>> specificationComposites = abstractCompositeSpecification.specifications;
184                 for (Specification<? super Entity> specificationComposite : specificationComposites) {
185                     if (specificationComposite instanceof CompositeSpecification) {
186                         if (!isTypeOnlyCompositeSpecification((CompositeSpecification<Entity>) specificationComposite)) {
187                             if (specificationComposite instanceof JointDenialSpecification || negated) {
188                                 buildHqlFromCompositeSpecification((CompositeSpecification<Entity>) specificationComposite,
189                                                                    parentParameterizedSpecification,
190                                                                    true,
191                                                                    hqlExpression);
192                             } else {
193                                 buildHqlFromCompositeSpecification((CompositeSpecification<Entity>) specificationComposite,
194                                                                    parentParameterizedSpecification,
195                                                                    false,
196                                                                    hqlExpression);
197                             }
198                         }
199 
200                     } else if (specificationComposite instanceof ParameterizedSpecification) {
201                         ParameterizedSpecification parameterizedSpecification = (ParameterizedSpecification) specificationComposite;
202                         if (parameterizedSpecification.accessibleObjectSpecification instanceof CompositeSpecification) {
203                             buildHqlFromCompositeSpecification((CompositeSpecification<?>) parameterizedSpecification.accessibleObjectSpecification, parameterizedSpecification, false, hqlExpression);
204 
205                         } else if (parameterizedSpecification.accessibleObjectSpecification instanceof LeafSpecification) {
206                             LeafSpecification leafSpecification = (LeafSpecification) parameterizedSpecification.accessibleObjectSpecification;
207                             if (leafSpecification instanceof ValueBoundSpecification) {
208                                 if (leafSpecification instanceof EqualSpecification) {
209                                     ValueBoundSpecification valueBoundSpecification = (ValueBoundSpecification) leafSpecification;
210                                     final String name;
211                                     if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
212                                         name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
213                                     } else {
214                                         name = parameterizedSpecification.getName();
215                                     }
216                                     Object value = valueBoundSpecification.getValue();
217                                     hqlExpression.append(" where entity.");
218                                     hqlExpression.append(name);
219                                     hqlExpression.append(" = ");
220                                     hqlExpression.append(value);
221 
222                                 } else if (leafSpecification instanceof GreaterThanSpecification) {
223                                     ValueBoundSpecification valueBoundSpecification = (ValueBoundSpecification) leafSpecification;
224                                     final String name;
225                                     if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
226                                         name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
227                                     } else {
228                                         name = parameterizedSpecification.getName();
229                                     }
230                                     Object value = valueBoundSpecification.getValue();
231                                     hqlExpression.append(" where entity.");
232                                     hqlExpression.append(name);
233                                     hqlExpression.append(" > ");
234                                     hqlExpression.append(value);
235 
236                                 } else if (leafSpecification instanceof LessThanSpecification) {
237                                     ValueBoundSpecification valueBoundSpecification = (ValueBoundSpecification) leafSpecification;
238                                     final String name;
239                                     if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
240                                         name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
241                                     } else {
242                                         name = parameterizedSpecification.getName();
243                                     }
244                                     Object value = valueBoundSpecification.getValue();
245                                     hqlExpression.append(" where entity.");
246                                     hqlExpression.append(name);
247                                     hqlExpression.append(" < ");
248                                     hqlExpression.append(value);
249                                 } else {
250                                     throw new NotImplementedException();
251                                 }
252 
253                             } else if (leafSpecification instanceof NotNullSpecification) {
254                                 final String name;
255                                 if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
256                                     name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
257                                 } else {
258                                     name = parameterizedSpecification.getName();
259                                 }
260                                 hqlExpression.append(" where entity.");
261                                 hqlExpression.append(name);
262                                 hqlExpression.append(" is not null");
263 
264                             } else if (leafSpecification instanceof DefaultValueSpecification) {
265                                 final String name;
266                                 if (parameterizedSpecification instanceof MethodParameterizedSpecification) {
267                                     name = convertSetterOrGetterMethodName2FieldName(parameterizedSpecification.getName());
268                                 } else {
269                                     name = parameterizedSpecification.getName();
270                                 }
271                                 hqlExpression.append(" where entity.");
272                                 hqlExpression.append(name);
273                                 if (negated) {
274                                     //hqlExpression.append(" <> ' '");
275                                     hqlExpression.append(" is not null");
276                                 } else {
277                                     //hqlExpression.append(" = ' '");
278                                     hqlExpression.append(" is null");
279                                 }
280                             } else {
281                                 throw new NotImplementedException();
282                             }
283 
284                         } else {
285                             throw new NotImplementedException();
286                         }
287 
288                     } else if (specificationComposite instanceof LeafSpecification) {
289                         if (specificationComposite instanceof NotNullSpecification) {
290                             if (negated) {
291                                 hqlExpression.append(" is null");
292                             } else {
293                                 hqlExpression.append(" is not null");
294                             }
295 
296                         } else if (specificationComposite instanceof ValueBoundSpecification) {
297                             if (specificationComposite instanceof GreaterThanSpecification) {
298                                 ValueBoundSpecification valueBoundSpecification = (ValueBoundSpecification) specificationComposite;
299                                 throw new NotImplementedException();
300 
301                             } else if (specificationComposite instanceof LessThanSpecification) {
302                                 ValueBoundSpecification valueBoundSpecification = (ValueBoundSpecification) specificationComposite;
303                                 if (negated) {
304                                     hqlExpression.append(" >= ");
305                                 } else {
306                                     hqlExpression.append(" < ");
307                                 }
308                                 hqlExpression.append(valueBoundSpecification.getValue());
309 
310                             } else {
311                                 throw new NotImplementedException();
312                             }
313 
314                         } else if (specificationComposite instanceof DefaultValueSpecification) {
315                             if (negated) {
316                                 //hqlExpression.append(" <> ' '");
317                                 hqlExpression.append(" is not null");
318                             } else {
319                                 //hqlExpression.append(" = ' '");
320                                 hqlExpression.append(" is null");
321                             }
322 
323                         } else {
324                             throw new NotImplementedException();
325                         }
326 
327                     } else {
328                         throw new NotImplementedException();
329                     }
330                 }
331             }
332 
333         } else {
334             log.warn("Specification is a " + CompositeSpecification.class.getName() +
335                      ", but is not extending " + AbstractCompositeSpecification.class.getName());
336         }
337     }
338 
339 
340     private static boolean isTypeOnlyCompositeSpecification(final CompositeSpecification<Entity> compositeSpecification) {
341         if (compositeSpecification instanceof AbstractCompositeSpecification) {
342             AbstractCompositeSpecification abstractCompositeSpecification = (AbstractCompositeSpecification) compositeSpecification;
343             return abstractCompositeSpecification.specifications.isEmpty();
344 
345         } else {
346             log.warn("Specification is a " + CompositeSpecification.class.getName() +
347                      ", but is not extending " + AbstractCompositeSpecification.class.getName());
348             return false;
349         }
350     }
351 }