+
+
+
+
+
+
\ 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();
+ }
+
+}