/* * Copyright 2016 requery.io * * 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 io.requery.processor; import io.requery.Column; import io.requery.ForeignKey; import io.requery.JunctionTable; import io.requery.ReferentialAction; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.TypeElement; import javax.lang.model.type.MirroredTypeException; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import java.util.LinkedHashSet; import java.util.List; import java.util.Optional; import java.util.Set; class JunctionTableAssociation implements AssociativeEntityDescriptor { private final JunctionTable table; private final Set<AssociativeReference> columns; private final TypeMirror typeMirror; JunctionTableAssociation(Elements elements, AttributeMember member, JunctionTable table) { this.table = table; this.columns = new LinkedHashSet<>(); Optional<? extends AnnotationValue> columnValues = Mirrors.findAnnotationMirror(member.element(), JunctionTable.class) .flatMap(m -> Mirrors.findAnnotationValue(m, "columns")); for (Column column : table.columns()) { ReferentialAction deleteAction = ReferentialAction.CASCADE; ReferentialAction updateAction = ReferentialAction.CASCADE; TypeElement referenceType = null; String referencedColumn = null; if (column.foreignKey().length > 0) { ForeignKey key = column.foreignKey()[0]; deleteAction = key.delete(); updateAction = key.update(); if (columnValues.isPresent()) { List mirrors = (List) columnValues.get().getValue(); AnnotationMirror mirror = null; for (Object m : mirrors) { String name = Mirrors.findAnnotationValue((AnnotationMirror) m, "name") .map(AnnotationValue::getValue) .map(Object::toString) .orElse(null); if (column.name().equals(name)) { mirror = (AnnotationMirror) m; break; } } if (mirror != null) { Optional<? extends AnnotationValue> keyValue = Mirrors.findAnnotationValue(mirror, "foreignKey"); if (keyValue.isPresent()) { List children = (List) keyValue.get().getValue(); AnnotationMirror keyMirror = (AnnotationMirror) children.get(0); referenceType = Mirrors.findAnnotationValue(keyMirror, "references") .map(value -> elements.getTypeElement( value.getValue().toString())) .orElse(null); referencedColumn = Mirrors.findAnnotationValue(keyMirror, "referencedColumn") .map(value -> value.getValue().toString()) .orElse(null); } } } } columns.add(new AssociativeReference(column.name(), referenceType, referencedColumn, deleteAction, updateAction)); } TypeMirror mirror = null; try { table.type(); } catch (MirroredTypeException e) { if (!e.getTypeMirror().toString().equals("void")) { mirror = e.getTypeMirror(); // easiest way to get the mirror } } this.typeMirror = mirror; } @Override public String name() { return table.name(); } @Override public Set<AssociativeReference> columns() { return columns; } @Override public Optional<TypeMirror> type() { return Optional.ofNullable(typeMirror); } }