001package io.ebeaninternal.server.dto; 002 003import io.ebean.ProfileLocation; 004import io.ebean.metric.MetricFactory; 005import io.ebean.metric.QueryPlanMetric; 006import io.ebeaninternal.api.SpiDtoQuery; 007 008/** 009 * Request to map a resultSet columns for a query into a DTO bean. 010 */ 011public class DtoMappingRequest { 012 013 private final Class type; 014 015 private final String label; 016 017 private final ProfileLocation profileLocation; 018 019 private final String sql; 020 021 private final boolean relaxedMode; 022 023 private final DtoColumn[] columnMeta; 024 025 public DtoMappingRequest(SpiDtoQuery query, String sql, DtoColumn[] columnMeta) { 026 this.type = query.getType(); 027 this.label = query.getPlanLabel(); 028 this.profileLocation = query.getProfileLocation(); 029 this.sql = sql; 030 this.relaxedMode = query.isRelaxedMode(); 031 this.columnMeta = columnMeta; 032 } 033 034 public DtoColumn[] getColumnMeta() { 035 return columnMeta; 036 } 037 038 public boolean isRelaxedMode() { 039 return relaxedMode; 040 } 041 042 public String getLabel() { 043 return label; 044 } 045 046 public String getSql() { 047 return sql; 048 } 049 050 public QueryPlanMetric createMetric() { 051 return MetricFactory.get().createQueryPlanMetric(type, label, profileLocation, sql); 052 } 053 054 /** 055 * Map all DB columns to setters. 056 */ 057 DtoReadSet[] mapSetters(DtoMeta meta) { 058 DtoReadSet[] setterProps = new DtoReadSet[columnMeta.length]; 059 for (int i = 0; i < columnMeta.length; i++) { 060 setterProps[i] = mapColumn(i, meta); 061 } 062 return setterProps; 063 } 064 065 /** 066 * Map DB columns after constructor to setters. 067 */ 068 DtoReadSet[] mapArgPlusSetters(DtoMeta meta, int firstOnes) { 069 DtoReadSet[] setterProps = new DtoReadSet[columnMeta.length - firstOnes]; 070 int pos = 0; 071 for (int i = firstOnes; i < columnMeta.length; i++) { 072 setterProps[pos++] = mapColumn(i, meta); 073 } 074 return setterProps; 075 } 076 077 private DtoReadSet mapColumn(int pos, DtoMeta meta) { 078 String label = columnMeta[pos].getLabel(); 079 DtoReadSet property = meta.findProperty(label); 080 if (property == null || property.isReadOnly()) { 081 if (isRelaxedMode()) { 082 property = DtoReadSetColumnSkip.INSTANCE; 083 } else { 084 throw new IllegalStateException(unableToMapColumnMessage(columnMeta[pos], meta)); 085 } 086 } 087 return property; 088 } 089 090 private String unableToMapColumnMessage(DtoColumn col, DtoMeta meta) { 091 return "Unable to map DB column " + col + " to a property with a setter method on " + meta.dtoType()+". Consider query.setRelaxedMode() to skip mapping this column."; 092 } 093 094}