/* * 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.Map; import javax.persistence.Temporal; import javax.persistence.metamodel.*; import javax.xml.stream.XMLStreamException; import org.hibernate.MappingException; import com.google.common.collect.Maps; 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 JPADomainExporter} exports JPA 2 metamodels to Querydsl expression types * * @author tiwe * */ public class JPADomainExporter extends AbstractDomainExporter { private final Metamodel metamodel; /** * Create a new JPADomainExporter instance * * @param targetFolder target folder * @param metamodel metamodel */ public JPADomainExporter(File targetFolder, Metamodel metamodel) { this("Q", "", targetFolder, SimpleSerializerConfig.DEFAULT, metamodel, Charset.defaultCharset()); } /** * Create a new JPADomainExporter instance * * @param namePrefix name prefix (default: Q) * @param targetFolder target folder * @param metamodel metamodel */ public JPADomainExporter(String namePrefix, File targetFolder, Metamodel metamodel) { this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, metamodel, Charset.defaultCharset()); } /** * Create a new JPADomainExporter instance * * @param namePrefix name prefix (default: Q) * @param targetFolder target folder * @param metamodel metamodel * @param charset charset (default: system charset) */ public JPADomainExporter(String namePrefix, File targetFolder, Metamodel metamodel, Charset charset) { this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, metamodel, charset); } /** * Create a new JPADomainExporter instance * * @param namePrefix name prefix (default: Q) * @param nameSuffix name suffix * @param targetFolder target folder * @param metamodel metamodel */ public JPADomainExporter(String namePrefix, String nameSuffix, File targetFolder, Metamodel metamodel) { this(namePrefix, nameSuffix, targetFolder, SimpleSerializerConfig.DEFAULT, metamodel, Charset.defaultCharset()); } /** * Create a new JPADomainExporter instance * * @param namePrefix name prefix (default: Q) * @param targetFolder target folder * @param serializerConfig serializer config * @param metamodel metamodel */ public JPADomainExporter(String namePrefix, File targetFolder, SerializerConfig serializerConfig, Metamodel metamodel) { this(namePrefix, "", targetFolder, serializerConfig, metamodel, Charset.defaultCharset()); } /** * Create a new JPADomainExporter instance * * @param namePrefix name prefix (default: Q) * @param targetFolder target folder * @param serializerConfig serializer config * @param metamodel metamodel * @param charset charset (default: system charset) */ public JPADomainExporter(String namePrefix, File targetFolder, SerializerConfig serializerConfig, Metamodel metamodel, Charset charset) { this(namePrefix, "", targetFolder, serializerConfig, metamodel, charset); } /** * Create a new JPADomainExporter instance * * @param namePrefix name prefix (default: Q) * @param nameSuffix name suffix (default: empty) * @param targetFolder target folder * @param serializerConfig serializer config * @param metamodel metamodel * @param charset charset (default: system charset) */ public JPADomainExporter(String namePrefix, String nameSuffix, File targetFolder, SerializerConfig serializerConfig, Metamodel metamodel, Charset charset) { super(namePrefix, nameSuffix, targetFolder, serializerConfig, charset); this.metamodel = metamodel; } @Override protected void collectTypes() throws IOException, XMLStreamException, ClassNotFoundException, NoSuchMethodException { Map<ManagedType<?>, EntityType> types = Maps.newHashMap(); for (ManagedType<?> managedType : metamodel.getManagedTypes()) { if (managedType instanceof MappedSuperclassType) { types.put(managedType, createSuperType(managedType.getJavaType())); } else if (managedType instanceof javax.persistence.metamodel.EntityType) { types.put(managedType, createEntityType(managedType.getJavaType())); } else if (managedType instanceof EmbeddableType) { types.put(managedType, createEmbeddableType(managedType.getJavaType())); } else { throw new IllegalArgumentException("Unknown type " + managedType); } } // handle properties for (Map.Entry<ManagedType<?>, EntityType> entry : types.entrySet()) { EntityType entityType = entry.getValue(); for (Attribute<?,?> attribute : entry.getKey().getDeclaredAttributes()) { handleProperty(entityType, entityType.getJavaClass(), attribute); } } } private void handleProperty(EntityType entityType, Class<?> cl, Attribute<?,?> p) throws NoSuchMethodException, ClassNotFoundException { Class<?> clazz = Object.class; try { clazz = p.getJavaType(); } catch (MappingException e) { // ignore } Type propertyType = getType(cl, clazz, p.getName()); AnnotatedElement annotated = getAnnotatedElement(cl, p.getName()); propertyType = getTypeOverride(propertyType, annotated); if (propertyType == null) { return; } if (p.isCollection()) { if (p instanceof MapAttribute) { MapAttribute<?,?,?> map = (MapAttribute<?,?,?>) p; Type keyType = typeFactory.get(map.getKeyJavaType()); Type valueType = typeFactory.get(map.getElementType().getJavaType()); valueType = getPropertyType(p, valueType); propertyType = new SimpleType(propertyType, normalize(propertyType.getParameters().get(0), keyType), normalize(propertyType.getParameters().get(1), valueType)); } else { Type valueType = typeFactory.get(((PluralAttribute<?,?,?>) p).getElementType().getJavaType()); valueType = getPropertyType(p, valueType); propertyType = new SimpleType(propertyType, normalize(propertyType.getParameters().get(0), valueType)); } } else { propertyType = getPropertyType(p, propertyType); } Property property = createProperty(entityType, p.getName(), propertyType, annotated); entityType.addProperty(property); } private Type getPropertyType(Attribute<?, ?> p, Type propertyType) { Temporal temporal = ((AnnotatedElement) p.getJavaMember()).getAnnotation(Temporal.class); if (temporal != null) { switch (temporal.value()) { case DATE: propertyType = propertyType.as(TypeCategory.DATE); break; case TIME: propertyType = propertyType.as(TypeCategory.TIME); break; case TIMESTAMP: propertyType = propertyType.as(TypeCategory.DATETIME); break; } } return propertyType; } }