diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..7574ee2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +out +PhoneXDbModelGenerator.jar +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* diff --git a/.idea/.name b/.idea/.name new file mode 100755 index 0000000..4536b24 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +PhoneXAndroidDbModelGenerator \ No newline at end of file diff --git a/.idea/checkstyle-idea.xml b/.idea/checkstyle-idea.xml new file mode 100755 index 0000000..969133d --- /dev/null +++ b/.idea/checkstyle-idea.xml @@ -0,0 +1,17 @@ + + + + + + + diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100755 index 0000000..b22c943 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,25 @@ + + + + + + diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100755 index 0000000..e206d70 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100755 index 0000000..ce7b3d9 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100755 index 0000000..2c8e377 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml new file mode 100755 index 0000000..922003b --- /dev/null +++ b/.idea/scopes/scope_settings.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100755 index 0000000..275077f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100755 index 0000000..6b2203b --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,1091 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Abstraction issues + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1374857424767 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No facets are configured + + + + + + + + bundler (v1.1.5, RVM: ruby-1.9.3-p194 [global] (1)) [gem] + + + + + + + + AppCode OC-139.1398.15 + + + + + + + + PhoneXAndroidDbModelGenerator + + + + + + + + IDEA IC-139.1117.1 + + + + + + + + hamcrest + + + + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e06d208 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + 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. + diff --git a/META-INF/plugin.xml b/META-INF/plugin.xml new file mode 100755 index 0000000..a75724f --- /dev/null +++ b/META-INF/plugin.xml @@ -0,0 +1,94 @@ + + + net.phonex.intellij.android.dbmodel + Android Parcelable and DB model code generator. + 0.7 + PhoneX + + Android Parcelable code generator by Michal Charmas. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PhoneXAndroidDbModelGenerator.iml b/PhoneXAndroidDbModelGenerator.iml new file mode 100755 index 0000000..e47bfd8 --- /dev/null +++ b/PhoneXAndroidDbModelGenerator.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README b/README new file mode 100755 index 0000000..e69de29 diff --git a/src/net/phonex/intellij/android/dbmodel/CodeGenerator.java b/src/net/phonex/intellij/android/dbmodel/CodeGenerator.java new file mode 100644 index 0000000..c34518e --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/CodeGenerator.java @@ -0,0 +1,483 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * Copyright (C) 2015 Dusan Klinec Ph4r05. + * + * 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 net.phonex.intellij.android.dbmodel; + +import com.google.common.base.CaseFormat; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import net.phonex.intellij.android.dbmodel.typeserializers.*; + +import java.util.ArrayList; +import java.util.List; + + +/** + * Quite a few changes here by Dallas Gutauckis [dallas@gutauckis.com] + */ +public class CodeGenerator { + public static final String CREATOR_NAME = "CREATOR"; + + private final String[] integerTypes = new String[] { + "byte", "double", "float", "int", "long", "short", "boolean", + "java.lang.Byte", "java.lang.Double", "java.lang.Float", + "java.lang.Integer", "java.lang.Long", "java.lang.Boolean"}; + + private final PsiClass mClass; + private final List mFields; + private final TypeSerializerFactory mTypeSerializerFactory; + + public CodeGenerator(PsiClass psiClass, List fields) { + mClass = psiClass; + mFields = fields; + + this.mTypeSerializerFactory = new ChainSerializerFactory( + new BundleSerializerFactory(), + new DateSerializerFactory(), + new EnumerationSerializerFactory(), + new ParcelableListSerializerFactory(), + new PrimitiveTypeSerializerFactory(), + new PrimitiveArraySerializerFactory(), + new ListSerializerFactory(), + new ParcelableSerializerFactory(), + new SerializableSerializerFactory() + ); + } + + private String generateStaticCreator(PsiClass psiClass) { + StringBuilder sb = new StringBuilder("public static final android.os.Parcelable.Creator<"); + + String className = psiClass.getName(); + + sb.append(className).append("> CREATOR = new android.os.Parcelable.Creator<").append(className).append(">(){") + .append("public ").append(className).append(" createFromParcel(android.os.Parcel source) {") + .append("return new ").append(className).append("(source);}") + .append("public ").append(className).append("[] newArray(int size) {") + .append("return new ").append(className).append("[size];}") + .append("};"); + return sb.toString(); + } + + private String generateConstructor(List fields, PsiClass psiClass) { + String className = psiClass.getName(); + + StringBuilder sb = new StringBuilder("private "); + + // Create the Parcelable-required constructor + sb.append(className).append("(android.os.Parcel in) {"); + + // Creates all of the deserialization methods for the given fields + for (PsiField field : fields) { + sb.append(getSerializerForType(field).readValue(field, "in")); + } + + sb.append("}"); + return sb.toString(); + } + + private String generateWriteToParcel(List fields) { + StringBuilder sb = new StringBuilder("@Override public void writeToParcel(android.os.Parcel dest, int flags) {"); + + for (PsiField field : fields) { + sb.append(getSerializerForType(field).writeValue(field, "dest", "flags")); + } + + sb.append("}"); + + return sb.toString(); + } + + private TypeSerializer getSerializerForType(PsiField field) { + return mTypeSerializerFactory.getSerializer(field.getType()); + } + + private String generateDescribeContents() { + return "@Override public int describeContents() { return 0; }"; + } + + public void generate() { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(mClass.getProject()); + + removeExistingParcelableImplementation(mClass); + + // Describe contents method + PsiMethod describeContentsMethod = elementFactory.createMethodFromText(generateDescribeContents(), mClass); + // Method for writing to the parcel + PsiMethod writeToParcelMethod = elementFactory.createMethodFromText(generateWriteToParcel(mFields), mClass); + + // Default constructor if needed + String defaultConstructorString = generateDefaultConstructor(mClass); + PsiMethod defaultConstructor = null; + + if (defaultConstructorString != null) { + defaultConstructor = elementFactory.createMethodFromText(defaultConstructorString, mClass); + } + + // Constructor + PsiMethod constructor = elementFactory.createMethodFromText(generateConstructor(mFields, mClass), mClass); + // CREATOR + PsiField creatorField = elementFactory.createFieldFromText(generateStaticCreator(mClass), mClass); + + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(mClass.getProject()); + + // Shorten all class references + styleManager.shortenClassReferences(addAsLast(describeContentsMethod)); + styleManager.shortenClassReferences(addAsLast(writeToParcelMethod)); + + // Only adds if available + if (defaultConstructor != null) { + styleManager.shortenClassReferences(addAsLast(defaultConstructor)); + } + + styleManager.shortenClassReferences(addAsLast(constructor)); + styleManager.shortenClassReferences(addAsLast(creatorField)); + + makeClassImplementParcelable(elementFactory); + } + + public void generateFields() { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(mClass.getProject()); + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(mClass.getProject()); + + List fields = new ArrayList(); + fields.add("public static final String TABLE = \""+mClass.getName()+"\"; // TODO: FIXME: fixThis"); + + for (PsiField field : mFields) { + String fieldName = getFieldName(field.getName()); + String curField = "public static final String "+fieldName+" = \""+field.getName()+"\";"; + fields.add(curField); + } + + for (String field : fields) { + PsiField curField = elementFactory.createFieldFromText(field, mClass); + styleManager.shortenClassReferences(addAsLast(curField)); + } + } + + public void generateFullProjection() { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(mClass.getProject()); + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(mClass.getProject()); + StringBuilder sb = new StringBuilder("public static final String[] FULL_PROJECTION = new String[] {\n"); + final int nmFields = mFields.size(); + int cnFields = 0; + + for (PsiField field : mFields) { + String fieldName = getFieldName(field.getName()); + String comma = cnFields + 1 == nmFields ? "" : ","; + + sb.append(fieldName).append(comma); + cnFields += 1; + } + sb.append("\n};\n"); + + PsiField projectionField = elementFactory.createFieldFromText(sb.toString(), mClass); + styleManager.shortenClassReferences(addAsLast(projectionField)); + } + + public void generateCreateTable() { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(mClass.getProject()); + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(mClass.getProject()); + + final String className = mClass.getQualifiedName(); + StringBuilder sb = new StringBuilder("public static final String CREATE_TABLE = \"CREATE TABLE IF NOT EXISTS \"\n"); + sb.append("+ TABLE\n"); + sb.append("+ \" (\"\n"); + + // Compute longest field name. + int maxFieldLen = 0; + for (PsiField field : mFields) { + String fieldName = getFieldName(field.getName()); + final int fLen = fieldName.length(); + if (fLen > maxFieldLen){ + maxFieldLen = fLen; + } + } + + // Build CREATE TABLE. + final int nmFields = mFields.size(); + int cnFields = 0; + for (PsiField field : mFields) { + String fieldName = getFieldName(field.getName()); + String comma = cnFields + 1 == nmFields ? "" : ","; + String sqlType = getSqlType(field); + cnFields += 1; + + if ("FIELD_ID".equalsIgnoreCase(fieldName)){ + sb.append("+ ").append(rightPad(fieldName, maxFieldLen+3)).append(" + \" INTEGER PRIMARY KEY AUTOINCREMENT").append(comma).append(" \"\n"); + continue; + } + + sb.append("+ ").append(rightPad(fieldName, maxFieldLen+3)).append(" + \" ").append(sqlType).append(comma).append(" \"\n"); + } + + sb.append("+ \");\";\n"); + + PsiField projectionField = elementFactory.createFieldFromText(sb.toString(), mClass); + styleManager.shortenClassReferences(addAsLast(projectionField)); + } + + public void generateCreateFromCursor() { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(mClass.getProject()); + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(mClass.getProject()); + + StringBuilder sb = new StringBuilder("private final void createFromCursor(Cursor c){\n" + + " int colCount = c.getColumnCount();\n" + + " for(int i=0; i 0){ + sb.append(" else "); + } + + String sqlDeserializer = getSqlDeserializer(field); + + sb.append("if (").append(fieldName).append(".equals(colname)){\n"); + sb.append("this.").append(field.getName()).append(" = ").append(sqlDeserializer).append(";\n"); + sb.append("}"); + cnFields += 1; + } + + if (nmFields > 0){ + sb.append("else {\n" + + "Log.w(THIS_FILE, \"Unknown column name: \" + colname);\n" + + "}"); + } + + sb.append("}\n}\n"); + + PsiMethod projectionField = elementFactory.createMethodFromText(sb.toString(), mClass); + styleManager.shortenClassReferences(addAsLast(projectionField)); + } + + public void generateGetDbContentValues() { + PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(mClass.getProject()); + JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(mClass.getProject()); + + StringBuilder sb = new StringBuilder("public ContentValues getDbContentValues() {\n" + + " ContentValues args = new ContentValues();"); + + final int nmFields = mFields.size(); + int cnFields = 0; + + for (PsiField field : mFields) { + String fieldName = getFieldName(field.getName()); + PsiType fieldType = field.getType(); + String cnType = fieldType.getCanonicalText(); + final boolean lastOne = cnFields + 1 == nmFields; + final boolean primitiveType = isPrimitiveType(fieldType); + if (!primitiveType){ + sb.append("if (this."+(field.getName())+" != null)\n"); + sb.append(" "); + } + + final String sqlSerializer = getSqlSerializer(field); + sb.append("args.put(" + fieldName + ", " + (sqlSerializer) + ");\n"); + + cnFields += 1; + } + + sb.append("return args;\n}"); + + PsiMethod projectionField = elementFactory.createMethodFromText(sb.toString(), mClass); + styleManager.shortenClassReferences(addAsLast(projectionField)); + + } + + private String rightPad(String name, int desiredSize){ + final int ln = name.length(); + if (desiredSize <= ln){ + return name; + } + + int toAdd = desiredSize - ln; + StringBuilder sb = new StringBuilder(name); + for(int i=0; i fields) { + new WriteCommandAction.Simple(psiClass.getProject(), psiClass.getContainingFile()) { + @Override + protected void run() throws Throwable { + new CodeGenerator(psiClass, fields).generateCreateFromCursor(); + } + }.execute(); + } + + + @Override + public void update(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + e.getPresentation().setEnabled(psiClass != null && !psiClass.isEnum() && !psiClass.isInterface()); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/CreateTableAction.java b/src/net/phonex/intellij/android/dbmodel/CreateTableAction.java new file mode 100644 index 0000000..1de892f --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/CreateTableAction.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 Dusan Klinec Ph4r05. + * + * 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 net.phonex.intellij.android.dbmodel; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.util.PsiUtils; + +import java.util.List; + +public class CreateTableAction extends AnAction { + + @Override + public void actionPerformed(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + + GenerateDialog dlg = new GenerateDialog(psiClass); + dlg.show(); + + if (dlg.isOK()) { + generateParcelable(psiClass, dlg.getSelectedFields()); + } + } + + private void generateParcelable(final PsiClass psiClass, final List fields) { + new WriteCommandAction.Simple(psiClass.getProject(), psiClass.getContainingFile()) { + @Override + protected void run() throws Throwable { + new CodeGenerator(psiClass, fields).generateCreateTable(); + } + }.execute(); + } + + + @Override + public void update(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + e.getPresentation().setEnabled(psiClass != null && !psiClass.isEnum() && !psiClass.isInterface()); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/FieldsAction.java b/src/net/phonex/intellij/android/dbmodel/FieldsAction.java new file mode 100644 index 0000000..d1e04ca --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/FieldsAction.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2015 Dusan Klinec Ph4r05. + * + * 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 net.phonex.intellij.android.dbmodel; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.util.PsiUtils; + +import java.util.List; + +public class FieldsAction extends AnAction { + + @Override + public void actionPerformed(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + + GenerateDialog dlg = new GenerateDialog(psiClass); + dlg.show(); + + if (dlg.isOK()) { + generateParcelable(psiClass, dlg.getSelectedFields()); + } + } + + private void generateParcelable(final PsiClass psiClass, final List fields) { + new WriteCommandAction.Simple(psiClass.getProject(), psiClass.getContainingFile()) { + @Override + protected void run() throws Throwable { + new CodeGenerator(psiClass, fields).generateFields(); + } + }.execute(); + } + + + @Override + public void update(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + e.getPresentation().setEnabled(psiClass != null && !psiClass.isEnum() && !psiClass.isInterface()); + } + + +} diff --git a/src/net/phonex/intellij/android/dbmodel/FullProjectionAction.java b/src/net/phonex/intellij/android/dbmodel/FullProjectionAction.java new file mode 100644 index 0000000..39290d4 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/FullProjectionAction.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 Dusan Klinec Ph4r05. + * + * 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 net.phonex.intellij.android.dbmodel; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.util.PsiUtils; + +import java.util.List; + +public class FullProjectionAction extends AnAction { + + @Override + public void actionPerformed(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + + GenerateDialog dlg = new GenerateDialog(psiClass); + dlg.show(); + + if (dlg.isOK()) { + generateParcelable(psiClass, dlg.getSelectedFields()); + } + } + + private void generateParcelable(final PsiClass psiClass, final List fields) { + new WriteCommandAction.Simple(psiClass.getProject(), psiClass.getContainingFile()) { + @Override + protected void run() throws Throwable { + new CodeGenerator(psiClass, fields).generateFullProjection(); + } + }.execute(); + } + + + @Override + public void update(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + e.getPresentation().setEnabled(psiClass != null && !psiClass.isEnum() && !psiClass.isInterface()); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/GenerateDialog.java b/src/net/phonex/intellij/android/dbmodel/GenerateDialog.java new file mode 100644 index 0000000..efd4d57 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/GenerateDialog.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel; + +import com.intellij.ide.util.DefaultPsiElementCellRenderer; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.LabeledComponent; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiModifier; +import com.intellij.ui.CollectionListModel; +import com.intellij.ui.ToolbarDecorator; +import com.intellij.ui.components.JBList; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Arrays; +import java.util.List; + +public class GenerateDialog extends DialogWrapper { + + private final LabeledComponent myComponent; + private CollectionListModel myFields; + + protected GenerateDialog(PsiClass psiClass) { + super(psiClass.getProject()); + setTitle("Select fields for Parcelable generation"); + + PsiField[] allFields = psiClass.getAllFields(); + PsiField[] fields = new PsiField[allFields.length]; + + int i = 0; + + for (PsiField field : allFields) { + // Exclude static fields + if (!field.hasModifierProperty(PsiModifier.STATIC)) { + fields[i++] = field; + } + } + + // i is post-incremented, so no need to add 1 for the count + fields = Arrays.copyOfRange(fields, 0, i); + + myFields = new CollectionListModel(fields); + + JBList fieldList = new JBList(myFields); + fieldList.setCellRenderer(new DefaultPsiElementCellRenderer()); + ToolbarDecorator decorator = ToolbarDecorator.createDecorator(fieldList); + decorator.disableAddAction(); + JPanel panel = decorator.createPanel(); + + myComponent = LabeledComponent.create(panel, "Fields to include in Parcelable"); + + init(); + } + + @Nullable + @Override + protected JComponent createCenterPanel() { + return myComponent; + } + + public List getSelectedFields() { + return myFields.getItems(); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/GetDbContentValuesAction.java b/src/net/phonex/intellij/android/dbmodel/GetDbContentValuesAction.java new file mode 100644 index 0000000..8403e5c --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/GetDbContentValuesAction.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 Dusan Klinec Ph4r05. + * + * 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 net.phonex.intellij.android.dbmodel; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.util.PsiUtils; + +import java.util.List; + +public class GetDbContentValuesAction extends AnAction { + + @Override + public void actionPerformed(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + + GenerateDialog dlg = new GenerateDialog(psiClass); + dlg.show(); + + if (dlg.isOK()) { + generateParcelable(psiClass, dlg.getSelectedFields()); + } + } + + private void generateParcelable(final PsiClass psiClass, final List fields) { + new WriteCommandAction.Simple(psiClass.getProject(), psiClass.getContainingFile()) { + @Override + protected void run() throws Throwable { + new CodeGenerator(psiClass, fields).generateGetDbContentValues(); + } + }.execute(); + } + + + @Override + public void update(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + e.getPresentation().setEnabled(psiClass != null && !psiClass.isEnum() && !psiClass.isInterface()); + } + +} diff --git a/src/net/phonex/intellij/android/dbmodel/ParcelableAction.java b/src/net/phonex/intellij/android/dbmodel/ParcelableAction.java new file mode 100644 index 0000000..08e6ac1 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/ParcelableAction.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.util.PsiUtils; + +import java.util.List; + +public class ParcelableAction extends AnAction { + + @Override + public void actionPerformed(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + + GenerateDialog dlg = new GenerateDialog(psiClass); + dlg.show(); + + if (dlg.isOK()) { + generateParcelable(psiClass, dlg.getSelectedFields()); + } + } + + private void generateParcelable(final PsiClass psiClass, final List fields) { + new WriteCommandAction.Simple(psiClass.getProject(), psiClass.getContainingFile()) { + @Override + protected void run() throws Throwable { + new CodeGenerator(psiClass, fields).generate(); + } + }.execute(); + } + + + @Override + public void update(AnActionEvent e) { + PsiClass psiClass = PsiUtils.getPsiClassFromContext(e); + e.getPresentation().setEnabled(psiClass != null && !psiClass.isEnum() && !psiClass.isInterface()); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/BundleSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/BundleSerializerFactory.java new file mode 100644 index 0000000..6a2d045 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/BundleSerializerFactory.java @@ -0,0 +1,26 @@ +package net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.BundleSerializer; + +/** + * Custom serializer factory for Date objects + * + * @author Dallas Gutauckis [dallas@gutauckis.com] + */ +public class BundleSerializerFactory implements TypeSerializerFactory { + private final BundleSerializer mSerializer; + + public BundleSerializerFactory() { + mSerializer = new BundleSerializer(); + } + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + if ("android.os.Bundle".equals(psiType.getCanonicalText())) { + return mSerializer; + } + + return null; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/ChainSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/ChainSerializerFactory.java new file mode 100644 index 0000000..04d7151 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/ChainSerializerFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.UnknownTypeSerializer; + +import java.util.Arrays; +import java.util.List; + +public class ChainSerializerFactory implements TypeSerializerFactory { + + private final List factories; + + public ChainSerializerFactory(TypeSerializerFactory... factories) { + this.factories = Arrays.asList(factories); + } + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + for (TypeSerializerFactory factory : factories) { + TypeSerializer serializer = factory.getSerializer(psiType); + if (serializer != null) { + return serializer; + } + } + return new UnknownTypeSerializer(psiType.getCanonicalText()); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/DateSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/DateSerializerFactory.java new file mode 100644 index 0000000..3ab0655 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/DateSerializerFactory.java @@ -0,0 +1,26 @@ +package net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.DateSerializer; + +/** + * Custom serializer factory for Date objects + * + * @author Dallas Gutauckis [dallas@gutauckis.com] + */ +public class DateSerializerFactory implements TypeSerializerFactory { + private final DateSerializer mSerializer; + + public DateSerializerFactory() { + mSerializer = new DateSerializer(); + } + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + if ("java.util.Date".equals(psiType.getCanonicalText())) { + return mSerializer; + } + + return null; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/EnumerationSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/EnumerationSerializerFactory.java new file mode 100644 index 0000000..edfa34f --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/EnumerationSerializerFactory.java @@ -0,0 +1,21 @@ +package net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import com.intellij.psi.impl.source.PsiClassReferenceType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.EnumerationSerializer; + +/** + * Modified by Dallas Gutauckis [dallas@gutauckis.com] + */ +public class EnumerationSerializerFactory implements TypeSerializerFactory { + private TypeSerializer mSerializer = new EnumerationSerializer(); + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + if (psiType instanceof PsiClassReferenceType && ((PsiClassReferenceType) psiType).resolve().isEnum()) { + return mSerializer; + } + + return null; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/ListSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/ListSerializerFactory.java new file mode 100644 index 0000000..14569a4 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/ListSerializerFactory.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.ListPrimitiveSerializer; +import net.phonex.intellij.android.dbmodel.util.PsiUtils; + +public class ListSerializerFactory implements TypeSerializerFactory { + private TypeSerializer mSerializer = new ListPrimitiveSerializer(); + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + if (PsiUtils.isOfType(psiType, "java.util.List")) { + return mSerializer; + } + + return null; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/ParcelableListSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/ParcelableListSerializerFactory.java new file mode 100644 index 0000000..a06a07e --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/ParcelableListSerializerFactory.java @@ -0,0 +1,29 @@ +package net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.ParcelableListSerializer; +import net.phonex.intellij.android.dbmodel.util.PsiUtils; + +/** + * Serializer factory for List fields of Parcelable objects + * + * @author Dallas Gutauckis [dallas@gutauckis.com] + */ +public class ParcelableListSerializerFactory implements TypeSerializerFactory { + + private ParcelableListSerializer mSerializer; + + public ParcelableListSerializerFactory() { + mSerializer = new ParcelableListSerializer(); + } + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + // There might actually be a way to do this w/ a Collection, but it might not be order-safe + if (PsiUtils.isTypedClass(psiType, "java.util.List", "android.os.Parcelable")) { + return mSerializer; + } + + return null; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/ParcelableSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/ParcelableSerializerFactory.java new file mode 100644 index 0000000..3c4c423 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/ParcelableSerializerFactory.java @@ -0,0 +1,24 @@ +package net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.ParcelableObjectSerializer; +import net.phonex.intellij.android.dbmodel.util.PsiUtils; + +/** + * Serializer factory for Parcelable objects + * + * @author Dallas Gutauckis [dallas@gutauckis.com] + */ +public class ParcelableSerializerFactory implements TypeSerializerFactory { + + private ParcelableObjectSerializer mSerializer = new ParcelableObjectSerializer(); + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + if (PsiUtils.isOfType(psiType, "android.os.Parcelable")) { + return mSerializer; + } + + return null; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/PrimitiveArraySerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/PrimitiveArraySerializerFactory.java new file mode 100644 index 0000000..673d917 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/PrimitiveArraySerializerFactory.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.BooleanSparseArraySerializer; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.PrimitiveArraySerializer; + +import java.util.HashMap; + +public class PrimitiveArraySerializerFactory implements TypeSerializerFactory { + private final HashMap handledTypes; + + public PrimitiveArraySerializerFactory() { + handledTypes = new HashMap(); + handledTypes.put("boolean[]", new PrimitiveArraySerializer("Boolean")); + handledTypes.put("byte[]", new PrimitiveArraySerializer("Byte")); + handledTypes.put("char[]", new PrimitiveArraySerializer("Char")); + handledTypes.put("double[]", new PrimitiveArraySerializer("Double")); + handledTypes.put("float[]", new PrimitiveArraySerializer("Float")); + handledTypes.put("int[]", new PrimitiveArraySerializer("Int")); + handledTypes.put("long[]", new PrimitiveArraySerializer("Long")); + handledTypes.put("java.lang.String[]", new PrimitiveArraySerializer("String")); + handledTypes.put("android.util.SparseBooleanArray", new BooleanSparseArraySerializer()); + } + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + return handledTypes.get(psiType.getCanonicalText()); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/PrimitiveTypeSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/PrimitiveTypeSerializerFactory.java new file mode 100644 index 0000000..2f27572 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/PrimitiveTypeSerializerFactory.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.BooleanPrimitiveSerializer; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.NullablePrimitivesSerializer; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.PrimitiveTypeSerializer; + +import java.util.HashMap; +import java.util.Map; + +public class PrimitiveTypeSerializerFactory implements TypeSerializerFactory { + + private final Map writeMethodsForTypes = new HashMap(); + + public PrimitiveTypeSerializerFactory() { + initPrimitives(); + initNullablePrimitives(); + } + + private void initNullablePrimitives() { + writeMethodsForTypes.put("byte", new PrimitiveTypeSerializer("Byte")); + writeMethodsForTypes.put("double", new PrimitiveTypeSerializer("Double")); + writeMethodsForTypes.put("float", new PrimitiveTypeSerializer("Float")); + writeMethodsForTypes.put("int", new PrimitiveTypeSerializer("Int")); + writeMethodsForTypes.put("long", new PrimitiveTypeSerializer("Long")); + writeMethodsForTypes.put("java.lang.String", new PrimitiveTypeSerializer("String")); + writeMethodsForTypes.put("boolean", new BooleanPrimitiveSerializer()); + } + + private void initPrimitives() { + writeMethodsForTypes.put("java.lang.Byte", new NullablePrimitivesSerializer("java.lang.Byte")); + writeMethodsForTypes.put("java.lang.Double", new NullablePrimitivesSerializer("java.lang.Double")); + writeMethodsForTypes.put("java.lang.Float", new NullablePrimitivesSerializer("java.lang.Float")); + writeMethodsForTypes.put("java.lang.Integer", new NullablePrimitivesSerializer("java.lang.Integer")); + writeMethodsForTypes.put("java.lang.Long", new NullablePrimitivesSerializer("java.lang.Long")); + writeMethodsForTypes.put("java.lang.Boolean", new NullablePrimitivesSerializer("java.lang.Boolean")); + } + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + return writeMethodsForTypes.get(psiType.getCanonicalText()); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/SerializableSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/SerializableSerializerFactory.java new file mode 100644 index 0000000..fe32003 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/SerializableSerializerFactory.java @@ -0,0 +1,30 @@ +package net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; +import net.phonex.intellij.android.dbmodel.typeserializers.serializers.SerializableObjectSerializer; + +/** + * Modified by Dallas Gutauckis [dallas@gutauckis.com] + */ +public class SerializableSerializerFactory implements TypeSerializerFactory { + private TypeSerializer mSerializer; + + public SerializableSerializerFactory() { + mSerializer = new SerializableObjectSerializer(); + } + + @Override + public TypeSerializer getSerializer(PsiType psiType) { + PsiType[] superTypes = psiType.getSuperTypes(); + + for (PsiType superType : superTypes) { + String canonicalText = superType.getCanonicalText(); + + if ("java.io.Serializable".equals(canonicalText)) { + return mSerializer; + } + } + + return null; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/TypeSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/TypeSerializer.java new file mode 100644 index 0000000..b5d2524 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/TypeSerializer.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiField; + +public interface TypeSerializer { + + String writeValue(PsiField field, String parcel, String flags); + + String readValue(PsiField field, String parcel); +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/TypeSerializerFactory.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/TypeSerializerFactory.java new file mode 100644 index 0000000..0363b3b --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/TypeSerializerFactory.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers; + +import com.intellij.psi.PsiType; + +public interface TypeSerializerFactory { + public TypeSerializer getSerializer(PsiType psiType); +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/BooleanPrimitiveSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/BooleanPrimitiveSerializer.java new file mode 100644 index 0000000..c621a49 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/BooleanPrimitiveSerializer.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +public class BooleanPrimitiveSerializer implements TypeSerializer { + + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".writeByte(" + field.getName() + " ? (byte) 1 : (byte) 0);"; + } + + @Override + public String readValue(PsiField field, String parcel) { + return "this." + field.getName() + " = " + parcel + ".readByte() != 0;"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/BooleanSparseArraySerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/BooleanSparseArraySerializer.java new file mode 100644 index 0000000..5c1be3e --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/BooleanSparseArraySerializer.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +public class BooleanSparseArraySerializer implements TypeSerializer { + + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".writeSparseBooleanArray(this." + field.getName() + ");"; + } + + @Override + public String readValue(PsiField field, String parcel) { + return "this." + field.getName() + " = " + parcel + ".readSparseBooleanArray();"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/BundleSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/BundleSerializer.java new file mode 100644 index 0000000..114772c --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/BundleSerializer.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +/** + * Custom serializer for Date objects to simplify parceling + * + * @author Dallas Gutauckis [dallas@gutauckis.com] + */ +public class BundleSerializer implements TypeSerializer { + + private static final String NULL_VALUE = "-1"; + + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".writeBundle(" + field.getName() + ");"; + } + + @Override + public String readValue(PsiField field, String parcel) { + return field.getName() + " = " + parcel + ".readBundle();"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/DateSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/DateSerializer.java new file mode 100644 index 0000000..77bd712 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/DateSerializer.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; +import org.apache.xmlbeans.impl.common.NameUtil; + +/** + * Custom serializer for Date objects to simplify parceling + * + * @author Dallas Gutauckis [dallas@gutauckis.com] + */ +public class DateSerializer implements TypeSerializer { + + private static final String NULL_VALUE = "-1"; + + @Override + public String writeValue(PsiField field, String parcel, String flags) { + String fieldName = field.getName(); + return String.format("%s.writeLong(%s != null ? %s.getTime() : %s);", parcel, fieldName, fieldName, NULL_VALUE); + } + + @Override + public String readValue(PsiField field, String parcel) { + String fieldName = field.getName(); + String tmpFieldName = NameUtil.upperCaseFirstLetter(fieldName); + String formatted = String.format("long tmp%s = %s.readLong(); " + + "this.%s = tmp%s == %s ? null : new java.util.Date(tmp%s);", tmpFieldName, parcel, fieldName, tmpFieldName, NULL_VALUE, tmpFieldName); + return formatted; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/EnumerationSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/EnumerationSerializer.java new file mode 100644 index 0000000..565dd92 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/EnumerationSerializer.java @@ -0,0 +1,25 @@ +package net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; +import org.apache.xmlbeans.impl.common.NameUtil; + +/** + * Modified by Dallas Gutauckis [dallas@gutauckis.com] + */ +public class EnumerationSerializer implements TypeSerializer { + @Override + public String writeValue(PsiField field, String parcel, String flags) { + String fieldName = field.getName(); + return String.format("%s.writeInt(this.%s == null ? -1 : this.%s.ordinal());", parcel, fieldName, fieldName); + } + + @Override + public String readValue(PsiField field, String parcel) { + String fieldName = field.getName(); + String tmpFieldName = NameUtil.upperCaseFirstLetter(fieldName); + String format = "int tmp%s = %s.readInt();" + + "this.%s = tmp%s == -1 ? null : %s.values()[tmp%s];"; + return String.format(format, tmpFieldName, parcel, fieldName, tmpFieldName, field.getType().getCanonicalText(), tmpFieldName); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/ListPrimitiveSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/ListPrimitiveSerializer.java new file mode 100644 index 0000000..08a73ae --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/ListPrimitiveSerializer.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +public class ListPrimitiveSerializer implements TypeSerializer { + + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".writeList(this." + field.getName() + ");"; + } + + @Override + public String readValue(PsiField field, String parcel) { + String typeName = field.getType().getCanonicalText(); + return "this." + field.getName() + " = new java.util.ArrayList<" + typeName + ">();" + + "in.readList(this." + field.getName() + " ," + typeName + ".class.getClassLoader());"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/NullablePrimitivesSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/NullablePrimitivesSerializer.java new file mode 100644 index 0000000..25703fb --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/NullablePrimitivesSerializer.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +public class NullablePrimitivesSerializer implements TypeSerializer { + + private final String typeName; + + public NullablePrimitivesSerializer(String typeName) { + this.typeName = typeName; + } + + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".writeValue(this." + field.getName() + ");"; + } + + @Override + public String readValue(PsiField field, String parcel) { + return "this." + field.getName() + " = (" + typeName + ")" + parcel + ".readValue(" + typeName + ".class.getClassLoader());"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/ParcelableListSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/ParcelableListSerializer.java new file mode 100644 index 0000000..df56887 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/ParcelableListSerializer.java @@ -0,0 +1,21 @@ +package net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; +import net.phonex.intellij.android.dbmodel.util.PsiUtils; + +/** + * @author Dallas Gutauckis [dallas@gutauckis.com] + */ +public class ParcelableListSerializer implements TypeSerializer { + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return String.format("%s.writeTypedList(%s);", parcel, field.getName()); + } + + @Override + public String readValue(PsiField field, String parcel) { + String paramType = PsiUtils.getResolvedGenerics(field.getType()).get(0).getCanonicalText(); + return String.format("%s.readTypedList(%s, %s.CREATOR);", parcel, field.getName(), paramType); + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/ParcelableObjectSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/ParcelableObjectSerializer.java new file mode 100644 index 0000000..fa1f943 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/ParcelableObjectSerializer.java @@ -0,0 +1,21 @@ +package net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +/** + * Serializer for types implementing Parcelable + * + * @author Dallas Gutauckis [dallas@gutauckis.com] + */ +public class ParcelableObjectSerializer implements TypeSerializer { + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".writeParcelable(this." + field.getName() + ", 0);"; + } + + @Override + public String readValue(PsiField field, String parcel) { + return "this." + field.getName() + " = " + parcel + ".readParcelable(" + field.getType().getCanonicalText() + ".class.getClassLoader());"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/PrimitiveArraySerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/PrimitiveArraySerializer.java new file mode 100644 index 0000000..e5ff5ec --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/PrimitiveArraySerializer.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +public class PrimitiveArraySerializer implements TypeSerializer { + + private final String type; + + public PrimitiveArraySerializer(String type) { + this.type = type; + } + + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".write" + type + "Array(this." + field.getName() + ");"; + } + + @Override + public String readValue(PsiField field, String parcel) { + return "this." + field.getName() + " = " + parcel + ".create" + type + "Array();"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/PrimitiveTypeSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/PrimitiveTypeSerializer.java new file mode 100644 index 0000000..c4f9e5f --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/PrimitiveTypeSerializer.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +public class PrimitiveTypeSerializer implements TypeSerializer { + + private final String typeName; + + public PrimitiveTypeSerializer(String typeName) { + this.typeName = typeName; + } + + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".write" + typeName + "(this." + field.getName() + ");"; + } + + @Override + public String readValue(PsiField field, String parcel) { + return "this." + field.getName() + " = " + parcel + ".read" + typeName + "();"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/SerializableObjectSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/SerializableObjectSerializer.java new file mode 100644 index 0000000..844be1f --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/SerializableObjectSerializer.java @@ -0,0 +1,19 @@ +package net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +/** + * Modified by Dallas Gutauckis [dallas@gutauckis.com] + */ +public class SerializableObjectSerializer implements TypeSerializer { + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".writeSerializable(this." + field.getName() + ");"; + } + + @Override + public String readValue(PsiField field, String parcel) { + return "this." + field.getName() + " = (" + field.getType().getCanonicalText() + ") " + parcel + ".readSerializable();"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/UnknownTypeSerializer.java b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/UnknownTypeSerializer.java new file mode 100644 index 0000000..199a225 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/typeserializers/serializers/UnknownTypeSerializer.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2013 Michał Charmas (http://blog.charmas.pl) + * + * 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 net.phonex.intellij.android.dbmodel.typeserializers.serializers; + +import com.intellij.psi.PsiField; +import net.phonex.intellij.android.dbmodel.typeserializers.TypeSerializer; + +public class UnknownTypeSerializer implements TypeSerializer { + + private final String typeName; + + public UnknownTypeSerializer(String typeName) { + this.typeName = typeName; + } + + @Override + public String writeValue(PsiField field, String parcel, String flags) { + return parcel + ".writeParcelable(this." + field.getName() + ", " + flags + ");"; + } + + @Override + public String readValue(PsiField field, String parcel) { + return "this." + field.getName() + " = " + parcel + ".readParcelable(" + this.typeName + ".class.getClassLoader());"; + } +} diff --git a/src/net/phonex/intellij/android/dbmodel/util/PsiUtils.java b/src/net/phonex/intellij/android/dbmodel/util/PsiUtils.java new file mode 100644 index 0000000..f0372c1 --- /dev/null +++ b/src/net/phonex/intellij/android/dbmodel/util/PsiUtils.java @@ -0,0 +1,115 @@ +package net.phonex.intellij.android.dbmodel.util; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.PlatformDataKeys; +import com.intellij.openapi.editor.Editor; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiTypesUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * Utils for introspecting Psi* stuff + * + * @author Dallas Gutauckis [dallas@gutauckis.com] + */ +final public class PsiUtils { + private PsiUtils() { + } + + public static PsiClass getPsiClassFromContext(AnActionEvent e) { + PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE); + Editor editor = e.getData(PlatformDataKeys.EDITOR); + + if (psiFile == null || editor == null) { + return null; + } + + int offset = editor.getCaretModel().getOffset(); + PsiElement element = psiFile.findElementAt(offset); + + return PsiTreeUtil.getParentOfType(element, PsiClass.class); + } + + /** + * Checks that the given type is an implementer of the given canonicalName with the given typed parameters + * + * @param type what we're checking against + * @param canonicalName the type must extend/implement this generic + * @param canonicalParamNames the type that the generic(s) must be (in this order) + * @return + */ + public static boolean isTypedClass(PsiType type, String canonicalName, String... canonicalParamNames) { + PsiClass parameterClass = PsiTypesUtil.getPsiClass(type); + + if (parameterClass == null) { + return false; + } + + // This is a safe cast, for if parameterClass != null, the type was checked in PsiTypesUtil#getPsiClass(...) + PsiClassType pct = (PsiClassType) type; + + // Main class name doesn't match; exit early + if (!canonicalName.equals(parameterClass.getQualifiedName())) { + return false; + } + + List psiTypes = new ArrayList(pct.resolveGenerics().getSubstitutor().getSubstitutionMap().values()); + + for (int i = 0; i < canonicalParamNames.length; i++) { + if (!isOfType(psiTypes.get(i), canonicalParamNames[i])) { + return false; + } + } + + // Passed all screenings; must be a match! + return true; + } + + /** + * Resolves generics on the given type and returns them (if any) or null if there are none + * + * @param type + * @return + */ + public static List getResolvedGenerics(PsiType type) { + List psiTypes = null; + + if (type instanceof PsiClassType) { + PsiClassType pct = (PsiClassType) type; + psiTypes = new ArrayList(pct.resolveGenerics().getSubstitutor().getSubstitutionMap().values()); + } + + return psiTypes; + } + + public static boolean isOfType(PsiType type, String canonicalName) { + if (type.getCanonicalText().equals(canonicalName)) { + return true; + } + + if (getNonGenericType(type).equals(canonicalName)) { + return true; + } + + for (PsiType iterType : type.getSuperTypes()) { + if (iterType.getCanonicalText().equals(canonicalName) || getNonGenericType(iterType).equals(canonicalName)) { + return true; + } + } + + return false; + } + + public static String getNonGenericType(PsiType type) { + if (type instanceof PsiClassType) { + PsiClassType pct = (PsiClassType) type; + return pct.resolve().getQualifiedName(); + } + + return type.getCanonicalText(); + } +} diff --git a/testSrc/net/phonex/utils/intellij/ios/dbmodel/builders/HashCodeBuilderTest.java b/testSrc/net/phonex/utils/intellij/ios/dbmodel/builders/HashCodeBuilderTest.java new file mode 100755 index 0000000..04ef8cf --- /dev/null +++ b/testSrc/net/phonex/utils/intellij/ios/dbmodel/builders/HashCodeBuilderTest.java @@ -0,0 +1,39 @@ +package net.phonex.utils.intellij.ios.dbmodel.builders; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class HashCodeBuilderTest { + +// private HashCodeBuilder underTest; +// private List fields = new ArrayList(); +// +// @Mock +// private PsiClass psiClass; +// @Mock +// private PsiField psiField1; +// @Mock +// private PsiField psiField2; +// @Mock +// private PsiClass superClass; + + @Before + public void setUp() throws Exception { +// fields.add(psiField1); +// fields.add(psiField2); +// +// underTest = new HashCodeBuilder(); + } + +}