com.querydsl.jpa.codegen.HibernateDomainExporter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of querydsl-jpa-codegen Show documentation
Show all versions of querydsl-jpa-codegen Show documentation
JPA Codegen support for Querydsl
/*
* Copyright 2015, The Querydsl Team (http://www.querydsl.com/team)
*
* 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 com.querydsl.jpa.codegen;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.AnnotatedElement;
import java.nio.charset.Charset;
import java.util.Iterator;
import javax.xml.stream.XMLStreamException;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.mapping.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.mysema.codegen.model.SimpleType;
import com.mysema.codegen.model.Type;
import com.mysema.codegen.model.TypeCategory;
import com.querydsl.codegen.EntityType;
import com.querydsl.codegen.Property;
import com.querydsl.codegen.SerializerConfig;
import com.querydsl.codegen.SimpleSerializerConfig;
/**
* {@code HibernateDomainExporter} exports Hibernate XML configuration files to Querydsl expression types
*
* @author tiwe
*
*/
public class HibernateDomainExporter extends AbstractDomainExporter {
private static final Logger logger = LoggerFactory.getLogger(HibernateDomainExporter.class);
private final Configuration configuration;
/**
* Create a new HibernateDomainExporter instance
*
* @param targetFolder target folder
* @param configuration configuration
*/
public HibernateDomainExporter(File targetFolder, Configuration configuration) {
this("Q", "", targetFolder, SimpleSerializerConfig.DEFAULT, configuration,
Charset.defaultCharset());
}
/**
* Create a new HibernateDomainExporter instance
*
* @param namePrefix name prefix (default: Q)
* @param targetFolder target folder
* @param configuration configuration
*/
public HibernateDomainExporter(String namePrefix, File targetFolder, Configuration configuration) {
this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, configuration,
Charset.defaultCharset());
}
/**
* Create a new HibernateDomainExporter instance
*
* @param namePrefix name prefix (default: Q)
* @param targetFolder target folder
* @param configuration configuration
* @param charset charset (default: system charset)
*/
public HibernateDomainExporter(String namePrefix, File targetFolder, Configuration configuration,
Charset charset) {
this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, configuration, charset);
}
/**
* Create a new HibernateDomainExporter instance
*
* @param namePrefix name prefix (default: Q)
* @param nameSuffix name suffix (default: empty)
* @param targetFolder target folder
* @param configuration configuration
*/
public HibernateDomainExporter(String namePrefix, String nameSuffix, File targetFolder,
Configuration configuration) {
this(namePrefix, nameSuffix, targetFolder, SimpleSerializerConfig.DEFAULT, configuration,
Charset.defaultCharset());
}
/**
* Create a new HibernateDomainExporter instance
*
* @param namePrefix name prefix (default Q)
* @param targetFolder target golder
* @param serializerConfig serializer config
* @param configuration configuration
*/
public HibernateDomainExporter(String namePrefix, File targetFolder,
SerializerConfig serializerConfig, Configuration configuration) {
this(namePrefix, "", targetFolder, serializerConfig, configuration, Charset.defaultCharset());
}
/**
* Create a new HibernateDomainExporter instance
*
* @param namePrefix name prefix (default: Q)
* @param targetFolder target folder
* @param serializerConfig serializer config
* @param configuration configuration
* @param charset charset (default: system charset)
*/
public HibernateDomainExporter(String namePrefix, File targetFolder,
SerializerConfig serializerConfig, Configuration configuration, Charset charset) {
this(namePrefix, "", targetFolder, serializerConfig, configuration, charset);
}
/**
* Create a new HibernateDomainExporter instance
*
* @param namePrefix name prefix (default: Q)
* @param nameSuffix name suffix (default: empty)
* @param targetFolder target folder
* @param serializerConfig serializer config
* @param configuration configuration
* @param charset charset (default: system charset)
*/
public HibernateDomainExporter(String namePrefix, String nameSuffix, File targetFolder,
SerializerConfig serializerConfig, Configuration configuration, Charset charset) {
super(namePrefix, nameSuffix, targetFolder, serializerConfig, charset);
configuration.buildMappings();
this.configuration = configuration;
}
@Override
protected void collectTypes() throws IOException, XMLStreamException, ClassNotFoundException,
NoSuchMethodException {
// super classes
Iterator> superClassMappings = configuration.getMappedSuperclassMappings();
while (superClassMappings.hasNext()) {
MappedSuperclass msc = (MappedSuperclass) superClassMappings.next();
EntityType entityType = createSuperType(msc.getMappedClass());
if (msc.getDeclaredIdentifierProperty() != null) {
handleProperty(entityType, msc.getMappedClass(), msc.getDeclaredIdentifierProperty());
}
Iterator> properties = msc.getDeclaredPropertyIterator();
while (properties.hasNext()) {
handleProperty(entityType, msc.getMappedClass(), (org.hibernate.mapping.Property) properties.next());
}
}
// entity classes
Iterator> classMappings = configuration.getClassMappings();
while (classMappings.hasNext()) {
PersistentClass pc = (PersistentClass) classMappings.next();
EntityType entityType = createEntityType(pc.getMappedClass());
if (pc.getDeclaredIdentifierProperty() != null) {
handleProperty(entityType, pc.getMappedClass(), pc.getDeclaredIdentifierProperty());
} else if (!pc.isInherited() && pc.hasIdentifierProperty()) {
logger.info(entityType.toString() + pc.getIdentifierProperty());
handleProperty(entityType, pc.getMappedClass(), pc.getIdentifierProperty());
} else if (pc.getIdentifier() != null) {
KeyValue identifier = pc.getIdentifier();
if (identifier instanceof Component) {
Component component = (Component) identifier;
Iterator> properties = component.getPropertyIterator();
if (component.isEmbedded()) {
while (properties.hasNext()) {
handleProperty(entityType, pc.getMappedClass(), (org.hibernate.mapping.Property) properties.next());
}
} else {
String name = component.getNodeName();
Class> clazz = component.getType().getReturnedClass();
Type propertyType = getType(pc.getMappedClass(), clazz, name);
AnnotatedElement annotated = getAnnotatedElement(pc.getMappedClass(), name);
Property property = createProperty(entityType, name, propertyType, annotated);
entityType.addProperty(property);
// handle component properties
EntityType embeddedType = createEmbeddableType(propertyType);
while (properties.hasNext()) {
handleProperty(embeddedType, clazz, (org.hibernate.mapping.Property) properties.next());
}
}
}
// TODO handle other KeyValue subclasses such as Any, DependentValue and ToOne
}
Iterator> properties = pc.getDeclaredPropertyIterator();
while (properties.hasNext()) {
handleProperty(entityType, pc.getMappedClass(), (org.hibernate.mapping.Property) properties.next());
}
}
}
private void handleProperty(EntityType entityType, Class> cl, org.hibernate.mapping.Property p)
throws NoSuchMethodException, ClassNotFoundException {
if (p.isBackRef()) {
return;
}
Class> clazz = Object.class;
try {
clazz = p.getType().getReturnedClass();
} catch (MappingException e) {
// ignore
}
Type propertyType = getType(cl, clazz, p.getName());
try {
propertyType = getPropertyType(p, propertyType);
} catch (MappingException e) {
// ignore
}
AnnotatedElement annotated = getAnnotatedElement(cl, p.getName());
propertyType = getTypeOverride(propertyType, annotated);
if (propertyType == null) {
return;
}
if (p.isComposite()) {
EntityType embeddedType = createEmbeddableType(propertyType);
Iterator> properties = ((Component) p.getValue()).getPropertyIterator();
while (properties.hasNext()) {
handleProperty(embeddedType, embeddedType.getJavaClass(), (org.hibernate.mapping.Property) properties.next());
}
propertyType = embeddedType;
} else if (propertyType.getCategory() == TypeCategory.ENTITY || p.getValue() instanceof ManyToOne) {
propertyType = createEntityType(propertyType);
} else if (propertyType.getCategory() == TypeCategory.CUSTOM) {
propertyType = createEmbeddableType(propertyType);
} else if (p.getValue() instanceof org.hibernate.mapping.Collection) {
org.hibernate.mapping.Collection collection = (org.hibernate.mapping.Collection) p.getValue();
if (collection.getElement() instanceof OneToMany) {
String entityName = ((OneToMany) collection.getElement()).getReferencedEntityName();
if (entityName != null) {
if (collection.isMap()) {
Type keyType = typeFactory.get(Class.forName(propertyType.getParameters().get(0).getFullName()));
Type valueType = typeFactory.get(Class.forName(entityName));
propertyType = new SimpleType(propertyType,
normalize(propertyType.getParameters().get(0), keyType),
normalize(propertyType.getParameters().get(1), valueType));
} else {
Type componentType = typeFactory.get(Class.forName(entityName));
propertyType = new SimpleType(propertyType,
normalize(propertyType.getParameters().get(0), componentType));
}
}
} else if (collection.getElement() instanceof Component) {
Component component = (Component) collection.getElement();
Class> embeddedClass = Class.forName(component.getComponentClassName());
EntityType embeddedType = createEmbeddableType(embeddedClass);
Iterator> properties = component.getPropertyIterator();
while (properties.hasNext()) {
handleProperty(embeddedType, embeddedClass, (org.hibernate.mapping.Property) properties.next());
}
}
}
Property property = createProperty(entityType, p.getName(), propertyType, annotated);
entityType.addProperty(property);
}
private Type getPropertyType(org.hibernate.mapping.Property p, Type propertyType) {
switch (propertyType.getCategory()) {
case DATE:
case TIME:
case DATETIME:
String type = p.getType().getName();
if ("time".equals(type)) {
propertyType = propertyType.as(TypeCategory.TIME);
} else if ("date".equals(type)) {
propertyType = propertyType.as(TypeCategory.DATE);
} else if ("timestamp".equals(type)) {
propertyType = propertyType.as(TypeCategory.DATETIME);
}
default:
}
return propertyType;
}
}