/*
* Copyright 2013 Guidewire Software, Inc.
*/
package gw.plugin.ij.refactor;
import com.intellij.psi.JavaDirectoryService;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.PsiModifierList;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.move.moveInner.MoveInnerHandler;
import com.intellij.refactoring.move.moveInner.MoveInnerOptions;
import gw.lang.reflect.gs.GosuClassTypeLoader;
import gw.plugin.ij.actions.GosuTemplatesFactory;
import gw.plugin.ij.lang.psi.impl.GosuClassFileImpl;
import org.jetbrains.annotations.NotNull;
/**
*/
public class MoveGosuInnerHandler implements MoveInnerHandler {
@NotNull
@Override
public PsiClass copyClass( @NotNull final MoveInnerOptions options ) {
PsiClass innerClass = options.getInnerClass();
PsiClass newClass;
if( options.getTargetContainer() instanceof PsiDirectory ) {
//newClass = JavaDirectoryService.getInstance().createClass( (PsiDirectory)options.getTargetContainer(), options.getNewClassName() );
String fileName = options.getNewClassName() + GosuClassTypeLoader.GOSU_CLASS_FILE_EXT;
GosuClassFileImpl gsFile = (GosuClassFileImpl)GosuTemplatesFactory.createFromTemplate(
(PsiDirectory)options.getTargetContainer(), options.getNewClassName(), fileName, GosuTemplatesFactory.GOSU_CLASS_TEMPLATE );
newClass = gsFile.getClasses()[0];
PsiDocComment defaultDocComment = newClass.getDocComment();
if( defaultDocComment != null && innerClass.getDocComment() == null ) {
innerClass = (PsiClass)innerClass.addAfter( defaultDocComment, null ).getParent();
}
newClass = (PsiClass)newClass.replace( innerClass );
PsiUtil.setModifierProperty( newClass, PsiModifier.STATIC, false );
PsiUtil.setModifierProperty( newClass, PsiModifier.PRIVATE, false );
PsiUtil.setModifierProperty( newClass, PsiModifier.PROTECTED, false );
final boolean makePublic = needPublicAccess( options.getOuterClass(), options.getTargetContainer() );
if( makePublic ) {
PsiUtil.setModifierProperty( newClass, PsiModifier.PUBLIC, true );
}
final PsiMethod[] constructors = newClass.getConstructors();
for( PsiMethod constructor : constructors ) {
final PsiModifierList modifierList = constructor.getModifierList();
modifierList.setModifierProperty( PsiModifier.PRIVATE, false );
modifierList.setModifierProperty( PsiModifier.PROTECTED, false );
if( makePublic ) {
modifierList.setModifierProperty( PsiModifier.PUBLIC, true );
}
}
}
else {
newClass = (PsiClass)options.getTargetContainer().add( innerClass );
}
newClass.setName( options.getNewClassName() );
return newClass;
}
protected static boolean needPublicAccess( @NotNull final PsiClass outerClass, final PsiElement targetContainer ) {
if( outerClass.isInterface() ) {
return true;
}
if( targetContainer instanceof PsiDirectory ) {
final PsiPackage targetPackage = JavaDirectoryService.getInstance().getPackage( (PsiDirectory)targetContainer );
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance( outerClass.getProject() );
if( targetPackage != null && !psiFacade.isInPackage( outerClass, targetPackage ) ) {
return true;
}
}
return false;
}
}