/*
* Copyright 2010 Semafor Informatik & Energie AG, Basel, Switzerland
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.semafor.gendas.service;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;
import ch.semafor.gendas.dao.ElementTypeDao;
import ch.semafor.gendas.dao.PropertyTypeDao;
import ch.semafor.gendas.model.CoreException;
import ch.semafor.gendas.model.ElementType;
import ch.semafor.gendas.model.PropertyType;
public class ElementTypeCreator extends Creator {
private final Logger logger = LoggerFactory.getLogger(ElementTypeCreator.class);
private ElementTypeDao elementTypeDao; // NOPMD by wildi on 9/21/10 6:16 AM
final private PropertyTypeDao propertyTypeDao; // NOPMD by wildi on 9/21/10
// 6:16 AM
final private Map<String, ElementType> elementTypes; // NOPMD by wildi on
// 9/21/10 6:16 AM
public ElementTypeCreator(final ElementTypeDao elementTypeDao,
final PropertyTypeDao propertyTypeDao) {
super();
this.elementTypeDao = elementTypeDao;
this.propertyTypeDao = propertyTypeDao;
this.elementTypes = new HashMap<String, ElementType>();
}
private ElementType getElementType(final String name) {
if (elementTypeDao.exists(name)) {
return elementTypeDao.findByName(name); // NOPMD by wildi on 9/21/10 6:14
// AM
}
ElementType et = elementTypes.get(name); // NOPMD by wildi on 9/21/10 6:14
// AM
if (et != null) { // NOPMD by wildi on 9/21/10 6:14 AM
et.setCreated();
} else {
logger.debug("Created Element Type {}", name);
et = new ElementType(name);
elementTypes.put(name, et);
}
return et;
}
/**
* get property type of method
*
* @param method
* @return property type
*/
protected PropertyType getPropertyType(final Method method) {
final String name = getPropertyName(method);
try {
if (propertyTypeDao.exists(name)) {
return propertyTypeDao.findByName(name); // NOPMD by wildi on 9/21/10
// 6:14 AM
}
} catch (CoreException e) {
logger.error("property {} not found", name);
}
final PropertyType p = new PropertyType(name); // NOPMD by wildi on 9/21/10
// 6:14 AM
return propertyTypeDao.save(p);
}
public ElementType create(final Class beanClass) {
final String name = beanClass.getCanonicalName();
final ElementType elementType = getElementType(name);
if (!elementType.isCreated()) {
// ToDo, unnest, PMD:AvoidDeeplyNestedIfStmts
ReflectionUtils.doWithMethods(beanClass,
new ReflectionUtils.MethodCallback() {
public void doWith(final Method method) {
if (method.getName().startsWith("get")
|| method.getName().startsWith("is")
&& !method.getName().equals("getClass")) {
final Class retType = method.getReturnType();
if (isPrimitiveType(retType)) {
final PropertyType propType = getPropertyType(method);
elementType.add(propType);
} else if (!retType.equals(java.lang.ClassLoader.class)
&& !retType.equals(java.lang.annotation.Annotation.class)
&& !retType.equals(java.lang.Class.class)) {
Class argType = retType;
if (retType.equals(java.util.List.class)) { // see above
final Class genArgType = getGenericArgType(method
.getGenericReturnType());
if (genArgType != null) {
argType = genArgType;
}
}
if (!elementType.hasChild(argType.getCanonicalName())
&& !elementType.getName().equals(
argType.getCanonicalName())) {
if( isPrimitiveType(argType)){
final PropertyType propType = getPropertyType(method);
logger.debug("adding list property {}", name );
elementType.add(propType);
}
logger.debug("adding reference {} for {}",
argType.getCanonicalName(), name);
elementType.addReference(create(argType));
}
}
}
}
}); // ToDo, unnest, PMD:AvoidDeeplyNestedIfStmts
}
return elementType;
}
}