diff --git a/.gitignore b/.gitignore
old mode 100644
new mode 100755
index f6b286c..15018f8
--- a/.gitignore
+++ b/.gitignore
@@ -38,3 +38,74 @@ captures/
# Keystore files
*.jks
+### Android template
+# Built application files
+
+# Files for the ART/Dalvik VM
+
+# Java class files
+
+# Generated files
+
+# Gradle files
+
+# Local configuration file (sdk path, etc)
+
+# Proguard folder generated by Eclipse
+
+# Log Files
+
+# Android Studio Navigation editor temp files
+
+# Android Studio captures folder
+
+# Intellij
+.idea/tasks.xml
+.idea/libraries
+
+# Keystore files
+
+# External native build folder generated in Android Studio 2.2 and later
+.externalNativeBuild
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff:
+
+# Sensitive or high-churn files:
+.idea/dataSources/
+.idea/dataSources.ids
+.idea/dataSources.xml
+.idea/dataSources.local.xml
+.idea/sqlDataSources.xml
+.idea/dynamic.xml
+.idea/uiDesigner.xml
+
+# Gradle:
+.idea/gradle.xml
+
+# Mongo Explorer plugin:
+.idea/mongoSettings.xml
+
+## File-based project format:
+*.iws
+
+## Plugin-specific files:
+
+# IntelliJ
+/out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+.idea
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
old mode 100644
new mode 100755
index 8dada3e..d7f19c7
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright {yyyy} {name of copyright owner}
+ Copyright 2017 Daisuke Nomura
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -198,4 +198,4 @@
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.
+ limitations under the License.
\ No newline at end of file
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
index 8418bbb..9fa2488
--- a/README.md
+++ b/README.md
@@ -1,2 +1,230 @@
-# KiiAnnotation
-Annotation Processor for KiiObject
+# KiiAnnotation: Annotation Processor for KiiObject
+
+[![Release](https://jitpack.io/v/daisuke-nomura/kiiannotation.svg)](https://jitpack.io/#daisuke-nomura/kiiannotation)
+
+KiiAnnotation is an Annotation Processor library for [KiiObject][kiiObject] of [Kii Cloud][kii].
+This library generates wrapper methods for KiiObject and builder of itself.
+
+##Sample usage
+
+First of all, define KiiBucket name and KiiObject details.
+
+ @GroupScope(name = "hoge")
+ public class Group {
+ @Key(key = "fuga")
+ private String name;
+ }
+
+Next, select "Build APK".
+
+ public class GroupBucket {
+ private KiiObject kiiObject;
+
+ private GroupBucket(KiiGroup kiiGroup) {
+ this.kiiObject = kiiGroup.bucket("hoge").object();
+ }
+
+ private GroupBucket(KiiObject kiiObject) {
+ this.kiiObject = kiiObject;
+ }
+
+ public static GroupBucket create(KiiGroup kiiGroup) {
+ return new com.kyaracter.kiiannotation.example.entity.GroupBucket(kiiGroup);
+ }
+
+ public static GroupBucket from(KiiObject kiiObject) {
+ return new com.kyaracter.kiiannotation.example.entity.GroupBucket(kiiObject);
+ }
+
+ public KiiObject kiiObject() {
+ return this.kiiObject;
+ }
+
+ public void name(String name) {
+ this.kiiObject.set("fuga", name);
+ }
+
+ public String name() {
+ return this.kiiObject.getString("fuga");
+ }
+
+ public static class Builder {
+ private String name;
+
+ private KiiGroup kiiGroup;
+
+ public Builder(KiiGroup kiiGroup) {
+ this.kiiGroup = kiiGroup;
+ }
+
+ public GroupBucket.Builder name(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public GroupBucket build() {
+ GroupBucket groupbucket = new GroupBucket(this.kiiGroup);
+ groupbucket.name(this.name);
+ return groupbucket;
+ }
+ }
+ }
+
+
+After that, write your code.
+
+ GroupBucket groupBucket = new GroupBucket.Builder(Kii.group("aaa"))
+ .name("bbb")
+ .build();
+
+
+If you like get/set**** or don't like builder, you could enable or disable it.
+
+
+###Application Scope
+@ApplicationScope
+
+ @ApplicationScope(name = "app", simplify = false, builder = false, suffix = "Data")
+ public class App {
+ @Key(key = "app")
+ private String name;
+
+ @Key(key = "count")
+ private int count;
+ }
+
+then
+
+ public class AppData {
+ private KiiObject kiiObject;
+
+ private AppData() {
+ this.kiiObject = com.kii.cloud.storage.Kii.bucket("app").object();
+ }
+
+ private AppData(KiiObject kiiObject) {
+ this.kiiObject = kiiObject;
+ }
+
+ public static AppData create() {
+ return new com.kyaracter.kiiannotation.example.entity.AppData();
+ }
+
+ public static AppData from(KiiObject kiiObject) {
+ return new com.kyaracter.kiiannotation.example.entity.AppData(kiiObject);
+ }
+
+ public KiiObject getKiiObject() {
+ return this.kiiObject;
+ }
+
+ public void setName(String name) {
+ this.kiiObject.set("app", name);
+ }
+
+ public void setCount(int count) {
+ this.kiiObject.set("count", count);
+ }
+
+ public String getName() {
+ return this.kiiObject.getString("app");
+ }
+
+ public int getCount() {
+ return this.kiiObject.getInt("count");
+ }
+ }
+
+You could change suffix of class name.
+The default suffix is 'Bucket'.
+
+
+###Group Scope
+@GroupScope
+
+refer to sample usage.
+
+###User Scope
+@UserScope
+
+ @UserScope(name = "user", builder = false)
+ public class User {
+ @Key(key = "user")
+ private String name;
+ }
+
+then
+
+ public class UserBucket {
+ private KiiObject kiiObject;
+
+ private UserBucket() {
+ this.kiiObject = com.kii.cloud.storage.Kii.user().bucket("user").object();
+ }
+
+ private UserBucket(KiiObject kiiObject) {
+ this.kiiObject = kiiObject;
+ }
+
+ public static UserBucket create() {
+ return new com.kyaracter.kiiannotation.example.entity.UserBucket();
+ }
+
+ public static UserBucket from(KiiObject kiiObject) {
+ return new com.kyaracter.kiiannotation.example.entity.UserBucket(kiiObject);
+ }
+
+ public KiiObject kiiObject() {
+ return this.kiiObject;
+ }
+
+ public void name(String name) {
+ this.kiiObject.set("user", name);
+ }
+
+ public String name() {
+ return this.kiiObject.getString("user");
+ }
+ }
+
+##Binaries
+
+ allprojects {
+ repositories {
+ maven { url "https://jitpack.io" }
+ }
+ }
+
+and
+
+ dependencies {
+ annotationProcessor 'com.github.daisuke-nomura.KiiAnnotation:processor:0.1.0'
+ compile 'com.github.daisuke-nomura:KiiAnnotation:0.1.0'
+ }
+
+If you using Android Studio 2.2 or below, use [android-apt][apt] instead of 'annotationProcessor'.
+
+##Bugs and Feedback
+
+Please use [GitHub Issues][issues].
+
+##License
+
+ Copyright 2017 Daisuke Nomura
+
+ 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.
+
+[kiiObject]: http://docs.kii.com/references/android/storage/latest/com/kii/cloud/storage/KiiObject.html
+[kii]: https://jp.kii.com/
+[apt]: https://bitbucket.org/hvisser/android-apt
+[issues]: https://github.com/daisuke-nomura/KiiAnnotation/issues
\ No newline at end of file
diff --git a/annotations/.gitignore b/annotations/.gitignore
new file mode 100755
index 0000000..796b96d
--- /dev/null
+++ b/annotations/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/annotations/build.gradle b/annotations/build.gradle
new file mode 100755
index 0000000..132004f
--- /dev/null
+++ b/annotations/build.gradle
@@ -0,0 +1,10 @@
+apply plugin: 'java'
+apply plugin: 'maven'
+
+group='com.github.daisuke-nomura'
+
+dependencies {
+}
+
+sourceCompatibility = "1.7"
+targetCompatibility = "1.7"
diff --git a/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/ApplicationScope.java b/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/ApplicationScope.java
new file mode 100755
index 0000000..7ed0137
--- /dev/null
+++ b/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/ApplicationScope.java
@@ -0,0 +1,16 @@
+package com.kyaracter.kiiannotation.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface ApplicationScope {
+ String name();
+ boolean simplify() default true;
+ boolean builder() default true;
+ String suffix() default "Bucket";
+}
diff --git a/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/GroupScope.java b/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/GroupScope.java
new file mode 100755
index 0000000..0426fb5
--- /dev/null
+++ b/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/GroupScope.java
@@ -0,0 +1,16 @@
+package com.kyaracter.kiiannotation.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface GroupScope {
+ String name();
+ boolean simplify() default true;
+ boolean builder() default true;
+ String suffix() default "Bucket";
+}
diff --git a/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/Key.java b/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/Key.java
new file mode 100755
index 0000000..a18e132
--- /dev/null
+++ b/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/Key.java
@@ -0,0 +1,13 @@
+package com.kyaracter.kiiannotation.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.CLASS)
+public @interface Key {
+ String key();
+}
diff --git a/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/UserScope.java b/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/UserScope.java
new file mode 100755
index 0000000..1a4acf5
--- /dev/null
+++ b/annotations/src/main/java/com/kyaracter/kiiannotation/annotations/UserScope.java
@@ -0,0 +1,16 @@
+package com.kyaracter.kiiannotation.annotations;
+
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.CLASS)
+public @interface UserScope {
+ String name();
+ boolean simplify() default true;
+ boolean builder() default true;
+ String suffix() default "Bucket";
+}
diff --git a/build.gradle b/build.gradle
new file mode 100755
index 0000000..69507f1
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.3.0-rc1'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
diff --git a/example/.gitignore b/example/.gitignore
new file mode 100755
index 0000000..796b96d
--- /dev/null
+++ b/example/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/example/build.gradle b/example/build.gradle
new file mode 100755
index 0000000..52fdd7a
--- /dev/null
+++ b/example/build.gradle
@@ -0,0 +1,34 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 25
+ buildToolsVersion "25.0.2"
+ defaultConfig {
+ applicationId "com.kyaracter.kiiannotation.sample"
+ minSdkVersion 21
+ targetSdkVersion 25
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ annotationProcessor project(':processor')
+ compile project(':annotations')
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:25.2.0'
+ compile 'com.android.support.constraint:constraint-layout:1.0.0-beta5'
+ testCompile 'junit:junit:4.12'
+ compile('com.kii:cloud-sdk:2.4.14') {
+ transitive = true
+ }
+}
\ No newline at end of file
diff --git a/example/proguard-rules.pro b/example/proguard-rules.pro
new file mode 100755
index 0000000..c7057e1
--- /dev/null
+++ b/example/proguard-rules.pro
@@ -0,0 +1,25 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in /Users/daisuke/Library/Android/sdk/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/example/src/androidTest/java/com/kyaracter/kiiannotation/example/ExampleInstrumentedTest.java b/example/src/androidTest/java/com/kyaracter/kiiannotation/example/ExampleInstrumentedTest.java
new file mode 100755
index 0000000..84dc592
--- /dev/null
+++ b/example/src/androidTest/java/com/kyaracter/kiiannotation/example/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.kyaracter.kiiannotation.example;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumentation test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() throws Exception {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.kyaracter.kiiannotation", appContext.getPackageName());
+ }
+}
diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml
new file mode 100755
index 0000000..ea92e83
--- /dev/null
+++ b/example/src/main/AndroidManifest.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/example/src/main/java/com/kyaracter/kiiannotation/example/MainActivity.java b/example/src/main/java/com/kyaracter/kiiannotation/example/MainActivity.java
new file mode 100755
index 0000000..31c5338
--- /dev/null
+++ b/example/src/main/java/com/kyaracter/kiiannotation/example/MainActivity.java
@@ -0,0 +1,26 @@
+package com.kyaracter.kiiannotation.example;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+import com.kii.cloud.storage.Kii;
+import com.kyaracter.kiiannotation.example.entity.AppData;
+import com.kyaracter.kiiannotation.example.entity.GroupBucket;
+import com.kyaracter.kiiannotation.example.entity.UserBucket;
+
+public class MainActivity extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ AppData appBucket = AppData.create();
+
+ GroupBucket groupBucket = new GroupBucket.Builder(Kii.group("aaa"))
+ .name("bbb")
+ .build();
+
+ UserBucket userBucket = UserBucket.create();
+ }
+}
diff --git a/example/src/main/java/com/kyaracter/kiiannotation/example/entity/App.java b/example/src/main/java/com/kyaracter/kiiannotation/example/entity/App.java
new file mode 100755
index 0000000..fe29ffb
--- /dev/null
+++ b/example/src/main/java/com/kyaracter/kiiannotation/example/entity/App.java
@@ -0,0 +1,14 @@
+package com.kyaracter.kiiannotation.example.entity;
+
+import com.kyaracter.kiiannotation.annotations.ApplicationScope;
+import com.kyaracter.kiiannotation.annotations.Key;
+
+
+@ApplicationScope(name = "app", simplify = false, builder = false, suffix = "Data")
+public class App {
+ @Key(key = "app")
+ private String name;
+
+ @Key(key = "count")
+ private int count;
+}
diff --git a/example/src/main/java/com/kyaracter/kiiannotation/example/entity/Group.java b/example/src/main/java/com/kyaracter/kiiannotation/example/entity/Group.java
new file mode 100755
index 0000000..0f96108
--- /dev/null
+++ b/example/src/main/java/com/kyaracter/kiiannotation/example/entity/Group.java
@@ -0,0 +1,11 @@
+package com.kyaracter.kiiannotation.example.entity;
+
+import com.kyaracter.kiiannotation.annotations.GroupScope;
+import com.kyaracter.kiiannotation.annotations.Key;
+
+
+@GroupScope(name = "hoge")
+public class Group {
+ @Key(key = "fuga")
+ private String name;
+}
diff --git a/example/src/main/java/com/kyaracter/kiiannotation/example/entity/User.java b/example/src/main/java/com/kyaracter/kiiannotation/example/entity/User.java
new file mode 100755
index 0000000..5acba5a
--- /dev/null
+++ b/example/src/main/java/com/kyaracter/kiiannotation/example/entity/User.java
@@ -0,0 +1,11 @@
+package com.kyaracter.kiiannotation.example.entity;
+
+
+import com.kyaracter.kiiannotation.annotations.Key;
+import com.kyaracter.kiiannotation.annotations.UserScope;
+
+@UserScope(name = "user", builder = false)
+public class User {
+ @Key(key = "user")
+ private String name;
+}
diff --git a/example/src/main/res/layout/activity_main.xml b/example/src/main/res/layout/activity_main.xml
new file mode 100755
index 0000000..f4243da
--- /dev/null
+++ b/example/src/main/res/layout/activity_main.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
diff --git a/example/src/main/res/mipmap-hdpi/ic_launcher.png b/example/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100755
index 0000000..cde69bc
Binary files /dev/null and b/example/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/example/src/main/res/mipmap-hdpi/ic_launcher_round.png b/example/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100755
index 0000000..9a078e3
Binary files /dev/null and b/example/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/example/src/main/res/mipmap-mdpi/ic_launcher.png b/example/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100755
index 0000000..c133a0c
Binary files /dev/null and b/example/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/example/src/main/res/mipmap-mdpi/ic_launcher_round.png b/example/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100755
index 0000000..efc028a
Binary files /dev/null and b/example/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/example/src/main/res/mipmap-xhdpi/ic_launcher.png b/example/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..bfa42f0
Binary files /dev/null and b/example/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/example/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/example/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100755
index 0000000..3af2608
Binary files /dev/null and b/example/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/example/src/main/res/mipmap-xxhdpi/ic_launcher.png b/example/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100755
index 0000000..324e72c
Binary files /dev/null and b/example/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/example/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/example/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100755
index 0000000..9bec2e6
Binary files /dev/null and b/example/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/example/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/example/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100755
index 0000000..aee44e1
Binary files /dev/null and b/example/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/example/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/example/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100755
index 0000000..34947cd
Binary files /dev/null and b/example/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/example/src/main/res/values/colors.xml b/example/src/main/res/values/colors.xml
new file mode 100755
index 0000000..3ab3e9c
--- /dev/null
+++ b/example/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #3F51B5
+ #303F9F
+ #FF4081
+
diff --git a/example/src/main/res/values/strings.xml b/example/src/main/res/values/strings.xml
new file mode 100755
index 0000000..fdc7ff9
--- /dev/null
+++ b/example/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ KiiAnnotation
+
diff --git a/example/src/main/res/values/styles.xml b/example/src/main/res/values/styles.xml
new file mode 100755
index 0000000..5885930
--- /dev/null
+++ b/example/src/main/res/values/styles.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
diff --git a/example/src/test/java/com/kyaracter/kiiannotation/example/ExampleUnitTest.java b/example/src/test/java/com/kyaracter/kiiannotation/example/ExampleUnitTest.java
new file mode 100755
index 0000000..4949fbf
--- /dev/null
+++ b/example/src/test/java/com/kyaracter/kiiannotation/example/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.kyaracter.kiiannotation.example;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() throws Exception {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100755
index 0000000..aac7c9b
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100755
index 0000000..13372ae
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100755
index 0000000..f838699
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sun Jan 08 22:49:47 JST 2017
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100755
index 0000000..8a0b282
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windowz variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+if "%@eval[2+2]" == "4" goto 4NT_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+goto execute
+
+:4NT_args
+@rem Get arguments from the 4NT Shell from JP Software
+set CMD_LINE_ARGS=%$
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/processor/.gitignore b/processor/.gitignore
new file mode 100755
index 0000000..796b96d
--- /dev/null
+++ b/processor/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/processor/build.gradle b/processor/build.gradle
new file mode 100755
index 0000000..f773de3
--- /dev/null
+++ b/processor/build.gradle
@@ -0,0 +1,12 @@
+apply plugin: 'java'
+apply plugin: 'maven'
+
+group='com.github.daisuke-nomura'
+
+dependencies {
+ compile project(':annotations')
+ compile 'com.squareup:javapoet:1.8.0'
+}
+
+sourceCompatibility = "1.8"
+targetCompatibility = "1.8"
diff --git a/processor/src/main/java/com/kyaracter/kiiannotation/processor/KiiAnnotationProcessor.java b/processor/src/main/java/com/kyaracter/kiiannotation/processor/KiiAnnotationProcessor.java
new file mode 100755
index 0000000..e4decfe
--- /dev/null
+++ b/processor/src/main/java/com/kyaracter/kiiannotation/processor/KiiAnnotationProcessor.java
@@ -0,0 +1,209 @@
+package com.kyaracter.kiiannotation.processor;
+
+
+import com.kyaracter.kiiannotation.annotations.ApplicationScope;
+import com.kyaracter.kiiannotation.annotations.GroupScope;
+import com.kyaracter.kiiannotation.annotations.Key;
+import com.kyaracter.kiiannotation.annotations.UserScope;
+import com.kyaracter.kiiannotation.processor.exception.IllegalAnnotationException;
+import com.kyaracter.kiiannotation.processor.exception.IllegalBucketNameException;
+import com.kyaracter.kiiannotation.processor.generator.ConstructorGenerator;
+import com.kyaracter.kiiannotation.processor.generator.FieldGenerator;
+import com.kyaracter.kiiannotation.processor.generator.GetterSetterGenerator;
+import com.kyaracter.kiiannotation.processor.generator.BuilderGenerator;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.TypeSpec;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+
+@SupportedSourceVersion(SourceVersion.RELEASE_8)
+@SupportedAnnotationTypes({
+ "com.kyaracter.kiiannotation.annotations.ApplicationScope",
+ "com.kyaracter.kiiannotation.annotations.GroupScope",
+ "com.kyaracter.kiiannotation.annotations.Key",
+ "com.kyaracter.kiiannotation.annotations.UserScope"
+})
+public class KiiAnnotationProcessor extends AbstractProcessor{
+
+ private Class extends Annotation> cls;
+ private boolean simplify;
+
+ @Override
+ public synchronized void init(ProcessingEnvironment processingEnvironment) {
+ super.init(processingEnvironment);
+ }
+
+ @Override
+ public boolean process(Set extends TypeElement> set, final RoundEnvironment roundEnvironment) {
+ List> list = new ArrayList<>();
+ list.add(ApplicationScope.class);
+ list.add(GroupScope.class);
+ list.add(UserScope.class);
+
+ list.stream()
+ .flatMap((Function, Stream extends Element>>) aClass -> {
+ cls = aClass;
+ return roundEnvironment.getElementsAnnotatedWith(aClass).stream();
+ })
+ .forEach(element -> {
+ final TypeElement typeElement = (TypeElement) element;
+
+ String bucketName;
+ boolean withBuilder;
+ final String packageName = processingEnv.getElementUtils().getPackageOf(element).getQualifiedName().toString();
+ final String regularClass = getRegularClassString(cls, typeElement);
+
+ final ClassName regularClassName = ClassName.get(packageName, regularClass);
+ final ClassName builderClassName = ClassName.get(packageName, regularClass + ".Builder");
+
+ //create regular class
+ final TypeSpec.Builder regularBuilder = TypeSpec
+ .classBuilder(regularClassName)
+ .addModifiers(Modifier.PUBLIC);
+
+ regularBuilder.addField(FieldGenerator.fieldKiiObject());
+
+ if (cls.equals(ApplicationScope.class)) {
+ ApplicationScope appBucketObject = typeElement.getAnnotation(ApplicationScope.class);
+ bucketName = appBucketObject.name();
+ simplify = appBucketObject.simplify();
+ withBuilder = appBucketObject.builder();
+ } else if (cls.equals(GroupScope.class)) {
+ GroupScope groupBucketObject = typeElement.getAnnotation(GroupScope.class);
+ bucketName = groupBucketObject.name();
+ simplify = groupBucketObject.simplify();
+ withBuilder = groupBucketObject.builder();
+ } else if (cls.equals(UserScope.class)) {
+ UserScope userBucketObject = typeElement.getAnnotation(UserScope.class);
+ bucketName = userBucketObject.name();
+ simplify = userBucketObject.simplify();
+ withBuilder = userBucketObject.builder();
+ } else {
+ throw new IllegalAnnotationException();
+ }
+
+ if (!Restriction.checkKii(bucketName)) {
+ throw new IllegalBucketNameException();
+ }
+
+ regularBuilder.addMethods(createConstructors(cls, bucketName, regularClassName));
+
+ regularBuilder.addMethod(GetterSetterGenerator.getKiiObject(simplify));
+
+ final List setterSpecList = new ArrayList<>();
+ final List getterSpecList = new ArrayList<>();
+ final List builderFieldSpecList = new ArrayList<>();
+ final List builderMethodSpecList = new ArrayList<>();
+
+ typeElement.getEnclosedElements()
+ .stream()
+ .filter((Predicate) element1 -> element1 instanceof VariableElement)
+ .forEach((Consumer) element2 -> {
+ if (element2.getAnnotation(Key.class) != null) {
+ System.out.println("Key");
+ setterSpecList.add(GetterSetterGenerator.setter(element2, simplify));
+ getterSpecList.add(GetterSetterGenerator.getter(element2, simplify));
+ builderFieldSpecList.add(BuilderGenerator.builderField(element2));
+ builderMethodSpecList.add(BuilderGenerator.builderMethod(builderClassName, element2));
+ } else {
+ throw new IllegalAnnotationException();
+ }
+ });
+
+ regularBuilder.addMethods(setterSpecList);
+ regularBuilder.addMethods(getterSpecList);
+
+ //create builder class in regular class
+ final TypeSpec.Builder builderBuilder = BuilderGenerator.builderInit();
+
+ if (withBuilder) {
+ builderBuilder.addFields(builderFieldSpecList);
+ builderBuilder.addMethods(builderMethodSpecList);
+
+ if (cls.equals(GroupScope.class)) {
+ //Group
+ builderBuilder.addField(BuilderGenerator.defaultGroupField());
+ builderBuilder.addMethod(BuilderGenerator.constructorGroupMethod());
+ builderBuilder.addMethod(BuilderGenerator.builderGroupBuild(regularClassName, setterSpecList, builderFieldSpecList));
+ } else {
+ builderBuilder.addMethod(BuilderGenerator.builderBuild(regularClassName, setterSpecList, builderFieldSpecList));
+ }
+
+ regularBuilder.addType(builderBuilder.build());
+ }
+
+ //write
+ final JavaFile javaFile = JavaFile.builder(packageName, regularBuilder.build()).build();
+
+ try {
+ javaFile.writeTo(processingEnv.getFiler());
+ } catch (IOException ioe) {
+
+ }
+ });
+
+ return false;
+ }
+
+ private static String getRegularClassString(Class extends Annotation> cls, TypeElement typeElement) {
+ if (cls.equals(ApplicationScope.class)) {
+ ApplicationScope appBucketObject = typeElement.getAnnotation(ApplicationScope.class);
+ return typeElement.getSimpleName() + appBucketObject.suffix();
+ } else if (cls.equals(GroupScope.class)) {
+ GroupScope groupBucketObject = typeElement.getAnnotation(GroupScope.class);
+ return typeElement.getSimpleName() + groupBucketObject.suffix();
+ } else if (cls.equals(UserScope.class)) {
+ UserScope userBucketObject = typeElement.getAnnotation(UserScope.class);
+ return typeElement.getSimpleName() + userBucketObject.suffix();
+ } else {
+ throw new IllegalAnnotationException();
+ }
+ }
+
+ private static List createConstructors(Class extends Annotation> cls, String bucketName, ClassName regularClassName) {
+ List methodSpecList = new ArrayList<>();
+
+ if (cls.equals(ApplicationScope.class)) {
+ methodSpecList.add(ConstructorGenerator.constructorApp(bucketName));
+ methodSpecList.add(ConstructorGenerator.constructor(bucketName));
+ methodSpecList.add(ConstructorGenerator.constructorCreate(regularClassName));
+ methodSpecList.add(ConstructorGenerator.constructorFrom(regularClassName));
+ } else if (cls.equals(GroupScope.class)) {
+ methodSpecList.add(ConstructorGenerator.constructorGroup(bucketName));
+ methodSpecList.add(ConstructorGenerator.constructor(bucketName));
+ methodSpecList.add(ConstructorGenerator.constructorCreateGroup(regularClassName));
+ methodSpecList.add(ConstructorGenerator.constructorFrom(regularClassName));
+ } else if (cls.equals(UserScope.class)) {
+ methodSpecList.add(ConstructorGenerator.constructorUser(bucketName));
+ methodSpecList.add(ConstructorGenerator.constructor(bucketName));
+ methodSpecList.add(ConstructorGenerator.constructorCreate(regularClassName));
+ methodSpecList.add(ConstructorGenerator.constructorFrom(regularClassName));
+ } else {
+ throw new IllegalAnnotationException();
+ }
+
+ return methodSpecList;
+ }
+}
diff --git a/processor/src/main/java/com/kyaracter/kiiannotation/processor/Restriction.java b/processor/src/main/java/com/kyaracter/kiiannotation/processor/Restriction.java
new file mode 100755
index 0000000..6fc03c7
--- /dev/null
+++ b/processor/src/main/java/com/kyaracter/kiiannotation/processor/Restriction.java
@@ -0,0 +1,45 @@
+package com.kyaracter.kiiannotation.processor;
+
+
+import java.util.regex.Pattern;
+
+public class Restriction {
+ private static boolean isReservedBucketName(String name) {
+ switch (name) {
+ case "users": return true;
+ case "devices": return true;
+ case "internal": return true;
+ case "things": return true;
+ }
+
+ return false;
+ }
+
+ private static boolean isStartUnderScore(String name) {
+ return Pattern.compile("^_").matcher(name).find();
+ }
+
+ private static boolean isCollectNameContentAndLength(String name) {
+ return Pattern.compile("^[A-Za-z0-9]{2,64}$").matcher(name).find();
+ }
+
+ public static boolean checkKii(String name) {
+ return !isReservedBucketName(name) && !isStartUnderScore(name) && isCollectNameContentAndLength(name);
+ }
+
+ private static boolean isReservedMethodName(String name) {
+ switch (name) {
+ case "this": return true;
+ case "kiiObject": return true;
+ case "getKiiObject": return true;
+ case "create": return true;
+ case "from": return true;
+ }
+
+ return false;
+ }
+
+ public static boolean checkJava(String name) {
+ return !isReservedMethodName(name);
+ }
+}
diff --git a/processor/src/main/java/com/kyaracter/kiiannotation/processor/exception/IllegalAnnotationException.java b/processor/src/main/java/com/kyaracter/kiiannotation/processor/exception/IllegalAnnotationException.java
new file mode 100755
index 0000000..76f4905
--- /dev/null
+++ b/processor/src/main/java/com/kyaracter/kiiannotation/processor/exception/IllegalAnnotationException.java
@@ -0,0 +1,5 @@
+package com.kyaracter.kiiannotation.processor.exception;
+
+
+public class IllegalAnnotationException extends IllegalArgumentException {
+}
diff --git a/processor/src/main/java/com/kyaracter/kiiannotation/processor/exception/IllegalBucketNameException.java b/processor/src/main/java/com/kyaracter/kiiannotation/processor/exception/IllegalBucketNameException.java
new file mode 100755
index 0000000..775e203
--- /dev/null
+++ b/processor/src/main/java/com/kyaracter/kiiannotation/processor/exception/IllegalBucketNameException.java
@@ -0,0 +1,5 @@
+package com.kyaracter.kiiannotation.processor.exception;
+
+
+public class IllegalBucketNameException extends IllegalArgumentException {
+}
diff --git a/processor/src/main/java/com/kyaracter/kiiannotation/processor/exception/ReservedWordException.java b/processor/src/main/java/com/kyaracter/kiiannotation/processor/exception/ReservedWordException.java
new file mode 100755
index 0000000..7d8df06
--- /dev/null
+++ b/processor/src/main/java/com/kyaracter/kiiannotation/processor/exception/ReservedWordException.java
@@ -0,0 +1,5 @@
+package com.kyaracter.kiiannotation.processor.exception;
+
+
+public class ReservedWordException extends Exception {
+}
diff --git a/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/BuilderGenerator.java b/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/BuilderGenerator.java
new file mode 100755
index 0000000..daf01f7
--- /dev/null
+++ b/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/BuilderGenerator.java
@@ -0,0 +1,105 @@
+package com.kyaracter.kiiannotation.processor.generator;
+
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+
+import java.util.List;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+
+public class BuilderGenerator {
+ public static TypeSpec.Builder builderInit() {
+ return TypeSpec
+ .classBuilder("Builder")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC);
+ }
+
+ public static FieldSpec builderField(Element element) {
+ Name name = element.getSimpleName();
+
+ return FieldSpec
+ .builder(TypeName.get(element.asType()), name.toString())
+ .addModifiers(Modifier.PRIVATE)
+ .build();
+ }
+
+ public static MethodSpec builderMethod(ClassName className, Element element) {
+ Name name = element.getSimpleName();
+
+ ParameterSpec parameterSpec = ParameterSpec.builder(TypeName.get(element.asType()), name.toString()).build();
+
+ return MethodSpec
+ .methodBuilder(name.toString())
+ .addModifiers(Modifier.PUBLIC)
+ .addParameter(parameterSpec)
+ .addStatement("this.$N = $N", name.toString(), name.toString())
+ .returns(className)
+ .addStatement("return this")
+ .build();
+ }
+
+ public static MethodSpec builderBuild(ClassName className, List methodSpecList, List fieldSpecList) {
+ String name = className.simpleName();
+ CodeBlock.Builder codeBlock = CodeBlock.builder();
+
+ for (int i = 0; i < methodSpecList.size(); i++) {
+ codeBlock.add("$N.$N(this.$N);\n", name.toLowerCase(), methodSpecList.get(i).name, fieldSpecList.get(i).name);
+ }
+
+ return MethodSpec
+ .methodBuilder("build")
+ .addModifiers(Modifier.PUBLIC)
+ .addStatement("$N $N = new $N()", name, name.toLowerCase(), name)
+ .addCode(codeBlock.build())
+ .returns(className)
+ .addStatement("return $N", name.toLowerCase())
+ .build();
+ }
+
+ public static FieldSpec defaultGroupField() {
+ ClassName className = ClassName.get("com.kii.cloud.storage", "KiiGroup");
+
+ return FieldSpec
+ .builder(className, "kiiGroup")
+ .addModifiers(Modifier.PRIVATE)
+ .build();
+ }
+
+ public static MethodSpec constructorGroupMethod() {
+ ClassName className = ClassName.get("com.kii.cloud.storage", "KiiGroup");
+ ParameterSpec parameterSpec = ParameterSpec.builder(className, "kiiGroup").build();
+
+ return MethodSpec
+ .constructorBuilder()
+ .addModifiers(Modifier.PUBLIC)
+ .addParameter(parameterSpec)
+ .addStatement("this.kiiGroup = kiiGroup")
+ .build();
+ }
+
+ public static MethodSpec builderGroupBuild(ClassName className, List methodSpecList, List fieldSpecList) {
+ String name = className.simpleName();
+ CodeBlock.Builder codeBlock = CodeBlock.builder();
+
+ for (int i = 0; i < methodSpecList.size(); i++) {
+ codeBlock.add("$N.$N(this.$N);\n", name.toLowerCase(), methodSpecList.get(i).name, fieldSpecList.get(i).name);
+ }
+
+ return MethodSpec
+ .methodBuilder("build")
+ .addModifiers(Modifier.PUBLIC)
+ .addStatement("$N $N = new $N($N)", name, name.toLowerCase(), name, "this.kiiGroup")
+ .addCode(codeBlock.build())
+ .returns(className)
+ .addStatement("return $N", name.toLowerCase())
+ .build();
+ }
+}
diff --git a/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/ConstructorGenerator.java b/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/ConstructorGenerator.java
new file mode 100755
index 0000000..8ddea4a
--- /dev/null
+++ b/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/ConstructorGenerator.java
@@ -0,0 +1,85 @@
+package com.kyaracter.kiiannotation.processor.generator;
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+
+import javax.lang.model.element.Modifier;
+
+
+public class ConstructorGenerator {
+ public static MethodSpec constructorApp(String name) {
+ return MethodSpec
+ .constructorBuilder()
+ .addModifiers(Modifier.PRIVATE)
+ .addStatement("this.kiiObject = com.kii.cloud.storage.Kii.bucket(\"$N\").object()", name)
+ .build();
+ }
+
+ public static MethodSpec constructorGroup(String name) {
+ ClassName className = ClassName.get("com.kii.cloud.storage", "KiiGroup");
+ ParameterSpec parameterSpec = ParameterSpec.builder(className, "kiiGroup").build();
+
+ return MethodSpec
+ .constructorBuilder()
+ .addModifiers(Modifier.PRIVATE)
+ .addParameter(parameterSpec)
+ .addStatement("this.kiiObject = kiiGroup.bucket(\"$N\").object()", name)
+ .build();
+ }
+
+ public static MethodSpec constructor(String name) {
+ ClassName className = ClassName.get("com.kii.cloud.storage", "KiiObject");
+ ParameterSpec parameterSpec = ParameterSpec.builder(className, "kiiObject").build();
+
+ return MethodSpec
+ .constructorBuilder()
+ .addModifiers(Modifier.PRIVATE)
+ .addParameter(parameterSpec)
+ .addStatement("this.kiiObject = kiiObject", name)
+ .build();
+ }
+
+ public static MethodSpec constructorUser(String name) {
+ return MethodSpec
+ .constructorBuilder()
+ .addModifiers(Modifier.PRIVATE)
+ .addStatement("this.kiiObject = com.kii.cloud.storage.Kii.user().bucket(\"$N\").object()", name)
+ .build();
+ }
+
+ public static MethodSpec constructorCreate(ClassName className) {
+ return MethodSpec
+ .methodBuilder("create")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .addStatement("return new $L()", className)
+ .returns(className)
+ .build();
+ }
+
+ public static MethodSpec constructorCreateGroup(ClassName className) {
+ ClassName className1 = ClassName.get("com.kii.cloud.storage", "KiiGroup");
+ ParameterSpec parameterSpec = ParameterSpec.builder(className1, "kiiGroup").build();
+
+ return MethodSpec
+ .methodBuilder("create")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .addParameter(parameterSpec)
+ .addStatement("return new $L($L)", className, "kiiGroup")
+ .returns(className)
+ .build();
+ }
+
+ public static MethodSpec constructorFrom(ClassName className) {
+ ClassName className1 = ClassName.get("com.kii.cloud.storage", "KiiObject");
+ ParameterSpec parameterSpec = ParameterSpec.builder(className1, "kiiObject").build();
+
+ return MethodSpec
+ .methodBuilder("from")
+ .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
+ .addParameter(parameterSpec)
+ .addStatement("return new $L($L)", className, "kiiObject")
+ .returns(className)
+ .build();
+ }
+}
diff --git a/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/FieldGenerator.java b/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/FieldGenerator.java
new file mode 100755
index 0000000..8df15d0
--- /dev/null
+++ b/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/FieldGenerator.java
@@ -0,0 +1,17 @@
+package com.kyaracter.kiiannotation.processor.generator;
+
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.FieldSpec;
+
+import javax.lang.model.element.Modifier;
+
+
+public class FieldGenerator {
+ public static FieldSpec fieldKiiObject() {
+ ClassName className = ClassName.get("com.kii.cloud.storage", "KiiObject");
+ return FieldSpec
+ .builder(className, "kiiObject")
+ .addModifiers(Modifier.PRIVATE)
+ .build();
+ }
+}
diff --git a/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/GetterSetterGenerator.java b/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/GetterSetterGenerator.java
new file mode 100755
index 0000000..2589f5b
--- /dev/null
+++ b/processor/src/main/java/com/kyaracter/kiiannotation/processor/generator/GetterSetterGenerator.java
@@ -0,0 +1,73 @@
+package com.kyaracter.kiiannotation.processor.generator;
+
+import com.kyaracter.kiiannotation.annotations.Key;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.TypeName;
+
+import java.util.Locale;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+
+
+public class GetterSetterGenerator {
+ public static MethodSpec getKiiObject(boolean simplify) {
+ ClassName className = ClassName.get("com.kii.cloud.storage", "KiiObject");
+ String getter = simplify ? "kiiObject" : getNotSimplifyName("get", "kiiObject");
+
+ return MethodSpec
+ .methodBuilder(getter)
+ .addModifiers(Modifier.PUBLIC)
+ .returns(className)
+ .addStatement("return this.kiiObject")
+ .build();
+ }
+
+ public static MethodSpec setter(Element element, boolean simplify) {
+ Key key = element.getAnnotation(Key.class);
+ String name = element.getSimpleName().toString();
+
+ ParameterSpec parameterSpec = ParameterSpec.builder(TypeName.get(element.asType()), name).build();
+
+ String setter = simplify ? name : getNotSimplifyName("set", name);
+
+ return MethodSpec
+ .methodBuilder(setter)
+ .addModifiers(Modifier.PUBLIC)
+ .addParameter(parameterSpec)
+ .addStatement("this.kiiObject.set(\"$N\", $N)", key.key(), name)
+ .build();
+ }
+
+ public static MethodSpec getter(Element element, boolean simplify) {
+ Key key = element.getAnnotation(Key.class);
+ String name = element.getSimpleName().toString();
+ TypeName typeName = TypeName.get(element.asType());
+
+ String getter = simplify ? name : getNotSimplifyName("get", name);
+
+ String type = getKiiGetter(typeName);
+
+ return MethodSpec
+ .methodBuilder(getter)
+ .addModifiers(Modifier.PUBLIC)
+ .returns(TypeName.get(element.asType()))
+ .addStatement("return this.kiiObject.get$N(\"$N\")", type, key.key())
+ .build();
+ }
+
+ public static String getKiiGetter(TypeName typeName) {
+ if (typeName.isPrimitive()) {
+ return String.format(Locale.US, "%s%s", typeName.toString().substring(0, 1).toUpperCase(), typeName.toString().substring(1, typeName.toString().length()));
+ } else {
+ String[] strings = typeName.toString().split("\\.");
+ return strings[strings.length - 1];
+ }
+ }
+
+ private static String getNotSimplifyName(String prefix, String name) {
+ return String.format(Locale.US, "%s%s%s", prefix, name.substring(0, 1).toUpperCase(), name.substring(1, name.length()));
+ }
+}
diff --git a/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
new file mode 100755
index 0000000..0637482
--- /dev/null
+++ b/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -0,0 +1 @@
+com.kyaracter.kiiannotation.processor.KiiAnnotationProcessor
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
new file mode 100755
index 0000000..e93f587
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1 @@
+include ':example', ':processor', ':annotations'