package com.cedarsoft.serialization.generator.intellij.model; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiField; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiParameter; import com.intellij.psi.PsiType; import com.intellij.psi.util.PropertyUtil; import org.jetbrains.annotations.Nullable; import javax.annotation.Nonnull; /** * @author Johannes Schneider (<a href="mailto:js@cedarsoft.com">js@cedarsoft.com</a>) */ public class FieldAccessProvider { @Nonnull private final PsiClass classToSerialize; @Nullable private final PsiMethod constructor; public FieldAccessProvider( @Nonnull PsiClass classToSerialize ) { this.classToSerialize = classToSerialize; constructor = findLongestConstructor( classToSerialize ); } @Nullable public PsiMethod getConstructor() { return constructor; } @Nonnull public PsiClass getClassToSerialize() { return classToSerialize; } @Nonnull public FieldSetter getFieldAccess( @Nonnull PsiField field ) { @Nullable FieldSetter.ConstructorFieldSetter constructorFieldAccess = getConstructorAccess( field ); if ( constructorFieldAccess != null ) { return constructorFieldAccess; } return findSetter( field ); } @Nullable private FieldSetter.ConstructorFieldSetter getConstructorAccess( @Nonnull PsiField field ) { if ( constructor == null ) { return null; } for ( PsiParameter psiParameter : constructor.getParameterList().getParameters() ) { PsiType type = psiParameter.getType(); String name = psiParameter.getName(); if ( !field.getName().equals( name ) ) { continue; } if ( !field.getType().equals( type ) ) { continue; } return new FieldSetter.ConstructorFieldSetter( constructor.getParameterList().getParameterIndex( psiParameter ) ); } return null; } @Nonnull private static FieldSetter findSetter( @Nonnull PsiField field ) { @Nullable PsiMethod setter = PropertyUtil.findSetterForField( field ); if ( setter != null ) { return new FieldSetter.SetterFieldSetter( setter.getName() ); } return new FieldSetter.SetterFieldSetter( PropertyUtil.suggestSetterName( field ) ); } @Nonnull private Project getProject() { return classToSerialize.getProject(); } @javax.annotation.Nullable private static PsiMethod findLongestConstructor( @Nonnull PsiClass classToSerialize ) { PsiMethod bestConstructor = null; for ( PsiMethod constructor : classToSerialize.getConstructors() ) { if ( bestConstructor == null ) { bestConstructor = constructor; continue; } if ( constructor.getParameterList().getParameters().length > bestConstructor.getParameterList().getParameters().length ) { bestConstructor = constructor; } } return bestConstructor; } }