Skip to content

Commit

Permalink
Refactoring. Adding new fields to DB model is easier.
Browse files Browse the repository at this point in the history
* DB field constants are added in-order with previously added constants. Only missing and different fields are added.
* If method exists, the new one is added right after the previous one to make manual merge easier and keep git diff short.
  • Loading branch information
ph4r05 committed Mar 8, 2015
1 parent 418c741 commit 37e5979
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 18 deletions.
6 changes: 3 additions & 3 deletions META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,19 @@
</action>

<action id="generateCreateTable" class="net.phonex.intellij.android.dbmodel.CreateTableAction"
text="createTable"
text="createTable()"
description="Generates Android DB model createTable field">
<add-to-group group-id="GenerateGroup" anchor="last"/>
</action>

<action id="generateCreateFromCursor" class="net.phonex.intellij.android.dbmodel.CreateFromCursorAction"
text="createFromCursor"
text="createFromCursor()"
description="Generates Android DB model createFromCursor method">
<add-to-group group-id="GenerateGroup" anchor="last"/>
</action>

<action id="generateGetDbContentValues" class="net.phonex.intellij.android.dbmodel.GetDbContentValuesAction"
text="getDbContentValues"
text="getDbContentValues()"
description="Generates Android DB model getDbContentValues method">
<add-to-group group-id="GenerateGroup" anchor="last"/>
</action>
Expand Down
59 changes: 44 additions & 15 deletions src/net/phonex/intellij/android/dbmodel/CodeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import net.phonex.intellij.android.dbmodel.typeserializers.*;
import net.phonex.intellij.android.dbmodel.util.FieldDef;
import net.phonex.intellij.android.dbmodel.util.NewFieldRecord;
import net.phonex.intellij.android.dbmodel.util.PsiUtils;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -152,18 +155,37 @@ public void generateFields() {
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(mClass.getProject());
JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(mClass.getProject());

List<String> fields = new ArrayList<String>();
fields.add("public static final String TABLE = \""+mClass.getName()+"\"; // TODO: FIXME: fixThis");

List<NewFieldRecord> newFields = new ArrayList<NewFieldRecord>();
newFields.add(new NewFieldRecord("TABLE", mClass.getName(), "TODO: verify"));
for (PsiField field : mFields) {
String fieldName = getFieldName(field.getName());
String curField = "public static final String "+fieldName+" = \""+field.getName()+"\";";
fields.add(curField);
newFields.add(new NewFieldRecord(fieldName, field.getName()));
}

for (String field : fields) {
PsiField curField = elementFactory.createFieldFromText(field, mClass);
styleManager.shortenClassReferences(addAsLast(curField));
PsiElement prevField = null;
for (NewFieldRecord newField : newFields) {
// Find if field is already present in file.
FieldDef prevFieldImpl = PsiUtils.findField(mClass, newField.name);
if (prevFieldImpl == null){
PsiField curField = elementFactory.createFieldFromText(newField.decl, mClass);
PsiElement element = prevField == null ? addAsLast(curField) : mClass.addAfter(curField, prevField);
prevField = styleManager.shortenClassReferences(element);
continue;
} else {
prevField = prevFieldImpl.field;
}

// Present, do we have exact match of the values?
final String valueInitializer = "\"" + newField.value + "\"";
if (newField.value.equals(prevFieldImpl.initializer) || valueInitializer.equals(prevFieldImpl.initializer)){
continue;
}

// Present and value differs, add anyway, but under previous field.
newField.addComment("TODO: verify");
PsiField curField = elementFactory.createFieldFromText(newField.decl, mClass);
PsiElement element = prevField == null ? addAsLast(curField) : mClass.addAfter(curField, prevField);
prevField = styleManager.shortenClassReferences(element);
}
}

Expand All @@ -183,8 +205,10 @@ public void generateFullProjection() {
}
sb.append("\n};\n");

FieldDef prevField = PsiUtils.findField(mClass, "FULL_PROJECTION");
PsiField projectionField = elementFactory.createFieldFromText(sb.toString(), mClass);
styleManager.shortenClassReferences(addAsLast(projectionField));
PsiElement element = prevField == null ? addAsLast(projectionField) : mClass.addAfter(projectionField, prevField.field);
styleManager.shortenClassReferences(element);
}

public void generateCreateTable() {
Expand Down Expand Up @@ -225,8 +249,10 @@ public void generateCreateTable() {

sb.append("+ \");\";\n");

FieldDef prevField = PsiUtils.findField(mClass, "CREATE_TABLE");
PsiField projectionField = elementFactory.createFieldFromText(sb.toString(), mClass);
styleManager.shortenClassReferences(addAsLast(projectionField));
PsiElement element = prevField == null ? addAsLast(projectionField) : mClass.addAfter(projectionField, prevField.field);
styleManager.shortenClassReferences(element);
}

public void generateCreateFromCursor() {
Expand Down Expand Up @@ -264,8 +290,10 @@ public void generateCreateFromCursor() {

sb.append("}\n}\n");

PsiMethod projectionField = elementFactory.createMethodFromText(sb.toString(), mClass);
styleManager.shortenClassReferences(addAsLast(projectionField));
PsiMethod prevMethod = PsiUtils.findMethod(mClass, "createFromCursor", "android.database.Cursor");
PsiMethod method = elementFactory.createMethodFromText(sb.toString(), mClass);
PsiElement element = prevMethod == null ? addAsLast(method) : mClass.addAfter(method, prevMethod);
styleManager.shortenClassReferences(element);
}

public void generateGetDbContentValues() {
Expand Down Expand Up @@ -297,9 +325,10 @@ public void generateGetDbContentValues() {

sb.append("return args;\n}");

PsiMethod projectionField = elementFactory.createMethodFromText(sb.toString(), mClass);
styleManager.shortenClassReferences(addAsLast(projectionField));

PsiMethod prevMethod = PsiUtils.findMethod(mClass, "getDbContentValues");
PsiMethod method = elementFactory.createMethodFromText(sb.toString(), mClass);
PsiElement element = prevMethod == null ? addAsLast(method) : mClass.addAfter(method, prevMethod);
styleManager.shortenClassReferences(element);
}

private String rightPad(String name, int desiredSize){
Expand Down
27 changes: 27 additions & 0 deletions src/net/phonex/intellij/android/dbmodel/util/FieldDef.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package net.phonex.intellij.android.dbmodel.util;

import com.intellij.psi.PsiField;

/**
* Created by dusanklinec on 08.03.15.
*/
public class FieldDef {
public String name;
public String initializer;
public PsiField field;

public FieldDef(String name, String initializer, PsiField field) {
this.name = name;
this.initializer = initializer;
this.field = field;
}

@Override
public String toString() {
return "FieldDef{" +
"name='" + name + '\'' +
", initializer='" + initializer + '\'' +
", field=" + field +
'}';
}
}
43 changes: 43 additions & 0 deletions src/net/phonex/intellij/android/dbmodel/util/NewFieldRecord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package net.phonex.intellij.android.dbmodel.util;

/**
* Created by dusanklinec on 08.03.15.
*/
public class NewFieldRecord {
public String decl;
public final String name;
public final String value;
public String comment;

public NewFieldRecord(String name, String value) {
this.name = name;
this.value = value;
setup();
}

public NewFieldRecord(String name, String value, String comment) {
this.value = value;
this.name = name;
this.comment = comment;
setup();
}

public void setup(){
this.decl = "extern NSString * " + name + "; \n";
if (comment == null) {
this.decl = "public static final String "+name+" = \""+value+"\";\n";
} else {
this.decl = "public static final String "+name+" = \""+value+"\"; //" + comment + "\n";
}
}

public void addComment(String s) {
if (this.comment == null){
this.comment = s;
} else {
this.comment = this.comment + "; " + s;
}

setup();
}
}
55 changes: 55 additions & 0 deletions src/net/phonex/intellij/android/dbmodel/util/PsiUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,59 @@ public static String getNonGenericType(PsiType type) {

return type.getCanonicalText();
}

public static PsiElement addLast(PsiElement elem, PsiElement where){
return where.addBefore(elem, where.getLastChild());
}

public static PsiMethod findMethod(PsiClass cls, String methodName, String... arguments) {
if (cls == null){
return null;
}

// Maybe there's an easier way to do this with mClass.findMethodBySignature(), but I'm not an expert on Psi*
PsiMethod[] methods = cls.findMethodsByName(methodName, false);
for (PsiMethod method : methods) {
PsiParameterList parameterList = method.getParameterList();

if (parameterList.getParametersCount() == arguments.length) {
boolean shouldReturn = true;

PsiParameter[] parameters = parameterList.getParameters();

for (int i = 0; i < arguments.length; i++) {
if (!parameters[i].getType().getCanonicalText().equals(arguments[i])) {
shouldReturn = false;
}
}

if (shouldReturn) {
return method;
}
}
}

return null;
}

public static FieldDef findField(PsiClass cls, String fieldName){
if (cls == null){
return null;
}

PsiField field = cls.findFieldByName(fieldName, true);
if (field == null){
return null;
}

String initializerString = null;
final PsiExpression initializer = field.getInitializer();
if (initializer instanceof PsiLiteralExpression){
final PsiLiteralExpression itext = (PsiLiteralExpression) initializer;
initializerString = itext.getText();
}

return new FieldDef(field.getName(), initializerString, field);
}

}

0 comments on commit 37e5979

Please sign in to comment.