diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..fe5f770 --- /dev/null +++ b/.cproject @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..7800d38 --- /dev/null +++ b/.project @@ -0,0 +1,82 @@ + + + cm + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/CleverModels/Debug} + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/Debug/java/subdir.mk b/Debug/java/subdir.mk new file mode 100644 index 0000000..b0f53e7 --- /dev/null +++ b/Debug/java/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../java/java_model_writer.c + +OBJS += \ +./java/java_model_writer.o + +C_DEPS += \ +./java/java_model_writer.d + + +# Each subdirectory must supply rules for building sources it contributes +java/%.o: ../java/%.c + @echo 'Building file: $<' + @echo 'Invoking: Cross GCC Compiler' + gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/Debug/makefile b/Debug/makefile new file mode 100644 index 0000000..5aab8f7 --- /dev/null +++ b/Debug/makefile @@ -0,0 +1,44 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +-include ../makefile.init + +RM := rm -rf + +# All of the sources participating in the build are defined here +-include sources.mk +-include java/subdir.mk +-include subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +-include ../makefile.defs + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: cm + +# Tool invocations +cm: $(OBJS) $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: Cross GCC Linker' + gcc -o "cm" $(OBJS) $(USER_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +# Other Targets +clean: + -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) cm + -@echo ' ' + +.PHONY: all clean dependents +.SECONDARY: + +-include ../makefile.targets diff --git a/Debug/objects.mk b/Debug/objects.mk new file mode 100644 index 0000000..742c2da --- /dev/null +++ b/Debug/objects.mk @@ -0,0 +1,8 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +USER_OBJS := + +LIBS := + diff --git a/Debug/sources.mk b/Debug/sources.mk new file mode 100644 index 0000000..9809635 --- /dev/null +++ b/Debug/sources.mk @@ -0,0 +1,18 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +O_SRCS := +C_SRCS := +S_UPPER_SRCS := +OBJ_SRCS := +ASM_SRCS := +OBJS := +C_DEPS := +EXECUTABLES := + +# Every subdirectory with source files must be described here +SUBDIRS := \ +. \ +java \ + diff --git a/Debug/subdir.mk b/Debug/subdir.mk new file mode 100644 index 0000000..c4b61f7 --- /dev/null +++ b/Debug/subdir.mk @@ -0,0 +1,36 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../clever_models.c \ +../helper_functions.c \ +../languages.c \ +../main.c \ +../model_builder.c + +OBJS += \ +./clever_models.o \ +./helper_functions.o \ +./languages.o \ +./main.o \ +./model_builder.o + +C_DEPS += \ +./clever_models.d \ +./helper_functions.d \ +./languages.d \ +./main.d \ +./model_builder.d + + +# Each subdirectory must supply rules for building sources it contributes +%.o: ../%.c + @echo 'Building file: $<' + @echo 'Invoking: Cross GCC Compiler' + gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/Release/java/subdir.mk b/Release/java/subdir.mk new file mode 100644 index 0000000..e5840aa --- /dev/null +++ b/Release/java/subdir.mk @@ -0,0 +1,24 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../java/java_model_writer.c + +OBJS += \ +./java/java_model_writer.o + +C_DEPS += \ +./java/java_model_writer.d + + +# Each subdirectory must supply rules for building sources it contributes +java/%.o: ../java/%.c + @echo 'Building file: $<' + @echo 'Invoking: Cross GCC Compiler' + gcc -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/Release/makefile b/Release/makefile new file mode 100644 index 0000000..5aab8f7 --- /dev/null +++ b/Release/makefile @@ -0,0 +1,44 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +-include ../makefile.init + +RM := rm -rf + +# All of the sources participating in the build are defined here +-include sources.mk +-include java/subdir.mk +-include subdir.mk +-include objects.mk + +ifneq ($(MAKECMDGOALS),clean) +ifneq ($(strip $(C_DEPS)),) +-include $(C_DEPS) +endif +endif + +-include ../makefile.defs + +# Add inputs and outputs from these tool invocations to the build variables + +# All Target +all: cm + +# Tool invocations +cm: $(OBJS) $(USER_OBJS) + @echo 'Building target: $@' + @echo 'Invoking: Cross GCC Linker' + gcc -o "cm" $(OBJS) $(USER_OBJS) $(LIBS) + @echo 'Finished building target: $@' + @echo ' ' + +# Other Targets +clean: + -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) cm + -@echo ' ' + +.PHONY: all clean dependents +.SECONDARY: + +-include ../makefile.targets diff --git a/Release/objects.mk b/Release/objects.mk new file mode 100644 index 0000000..742c2da --- /dev/null +++ b/Release/objects.mk @@ -0,0 +1,8 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +USER_OBJS := + +LIBS := + diff --git a/Release/sources.mk b/Release/sources.mk new file mode 100644 index 0000000..9809635 --- /dev/null +++ b/Release/sources.mk @@ -0,0 +1,18 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +O_SRCS := +C_SRCS := +S_UPPER_SRCS := +OBJ_SRCS := +ASM_SRCS := +OBJS := +C_DEPS := +EXECUTABLES := + +# Every subdirectory with source files must be described here +SUBDIRS := \ +. \ +java \ + diff --git a/Release/subdir.mk b/Release/subdir.mk new file mode 100644 index 0000000..f7020f8 --- /dev/null +++ b/Release/subdir.mk @@ -0,0 +1,36 @@ +################################################################################ +# Automatically-generated file. Do not edit! +################################################################################ + +# Add inputs and outputs from these tool invocations to the build variables +C_SRCS += \ +../clever_models.c \ +../helper_functions.c \ +../languages.c \ +../main.c \ +../model_builder.c + +OBJS += \ +./clever_models.o \ +./helper_functions.o \ +./languages.o \ +./main.o \ +./model_builder.o + +C_DEPS += \ +./clever_models.d \ +./helper_functions.d \ +./languages.d \ +./main.d \ +./model_builder.d + + +# Each subdirectory must supply rules for building sources it contributes +%.o: ../%.c + @echo 'Building file: $<' + @echo 'Invoking: Cross GCC Compiler' + gcc -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + + diff --git a/clever_models.c b/clever_models.c new file mode 100644 index 0000000..fa88d71 --- /dev/null +++ b/clever_models.c @@ -0,0 +1,252 @@ +// +// clever_models.c +// CleverModels +// +// Created by Bruno Martins on 3/27/12. +// Copyright (c) 2012. All rights reserved. +// + +#include +#include "constants.h" +#include "clever_models.h" +#include "helper_functions.h" +#include "model_builder.h" +#include "languages.h" + +unsigned int write_json_class_model(char name[], char json[], int language_code, char path[], char* class_headers, int multiple_objects) +{ + printf("entering for class : %s \n", name); + int opening_tag = 0; + int closing_tag = 0; + int opening_square_brackets = 0; + int closing_square_brackets = 0; + + char attributes[MAX_ATTRIBUTES][MAX_ATTRIBUTE_NAME_LENGTH]; + int attr_types[MAX_ATTRIBUTES]; + int nr_attributes = 0; + + FILE* implementation_file = 0; + FILE* header_file = 0; + create_class_files(name, path, language_code, class_headers, &implementation_file, &header_file); + write_class_header(name, language_code, implementation_file, header_file); + +// char* json = malloc(strlen(json) + 1); +// strncpy(json, json, strlen(json)); +// json[strlen(json)] = '\0'; + + int i; + for (i = 0; i < strlen(json); i++) { + char current_char = json[i]; + switch (current_char) { + case '{': + opening_tag++; + break; + + case ':': { + + //checking if : character is part of a string + //if not, meaning its part of key:value notation, we proceed + char next_char = (char)json[i+1]; + char prev_char = (char)json[i-1]; + if ('"' != prev_char && '"' != next_char) //found a : character whitin a string. Ignore! + continue; + + //Get the name of the attribute / key by finding the string between quotes + //#1 - get quotes position + int key_second_quote = str_pos_reverse('"', json, i, 1); + int key_first_quote = str_pos_reverse('"', json, i, 2); + + //printf("second_quote : %d, first_quote : %d \n", pos_attr_name_second_quote, pos_attr_name_first_quote); + + //#2 compute size of key/attribute + int length_attr_name = (key_second_quote - key_first_quote) - 1; + + //+1 for the string tail character + char attribute_name[length_attr_name + 1]; + //build attribute string & terminate string + strncpy(attribute_name, json + key_first_quote + 1, length_attr_name); + attribute_name[length_attr_name] = '\0'; + + printf("Class : %s -> Attribute name : %s, length : %d \n", name, attribute_name, length_attr_name); + + int attr_type = get_attribute_type(json, i); + if (0 == already_wrote_attribute(attribute_name, attributes, nr_attributes) && strcmp(":", attribute_name) != 0) { + //keep track of the attributes being added so we can generate getters & setters later on + int z; + for (z = 0; z <= length_attr_name; ++z) { + attributes[nr_attributes][z] = attribute_name[z]; + } + + attr_types[nr_attributes] = attr_type; + nr_attributes++; + + write_attribute(attribute_name, attr_type, language_code,implementation_file, header_file); + + if (TYPE_OBJECT == attr_type || TYPE_LIST == attr_type) { + int multiple = 0; + if (TYPE_LIST == attr_type) { + multiple = 1; + } + + char* partial_json = malloc(strlen(json+i+1)); + strncpy(partial_json, json+i+1, strlen(json+i+1)); + + i += write_json_class_model(attribute_name, partial_json, language_code, path, class_headers, multiple); + + + free(partial_json); + printf("# # back from class : %s rest json : %s, class name : %s, position : %d \n",attribute_name ,json+i, name, i); + } + } + + break; + } + + case '[': //array + opening_square_brackets++; + break; + + case '}': { + closing_tag++; + if (opening_tag == closing_tag) { + printf("# end of object ! rest json : %s, class name : %s, position : %d \n", json+i, name, i); + + if (opening_square_brackets > closing_square_brackets) { + //find position of the end of the list of objects of this type + i += find_pos_end_object_array(json+i); + } else { + i++; + } + goto close_class; + } + } + break; + + case ']': { + closing_square_brackets++; + if (opening_tag == closing_tag && closing_square_brackets == opening_square_brackets) { + printf("# end ] rest json : %s, class name : %s, position : %d \n", json+i, name, i); + i++; + goto close_class; + } + } + break; + default: + //ignore + break; + } + } + + close_class: + write_getters(implementation_file, header_file, language_code, attributes, attr_types, nr_attributes); + write_setters(implementation_file, header_file, language_code, attributes, attr_types, nr_attributes); + fprintf(implementation_file, "}"); + fclose(implementation_file); + if (NULL != header_file) { + fclose(implementation_file); + } + //free(mutable_json); + + return i; +} + +int get_attribute_type(char json[], int colon_pos) { + int attr_type = TYPE_OTHER; + char next_char = find_first_character(json + colon_pos + 1); + + switch (next_char) { + case '{': + attr_type = TYPE_OBJECT; + break; + + case '[': + attr_type = TYPE_LIST; + break; + + default: { + //try to find if attribute is a number,string or boolean + + //find ending character after the value + //its either } or , (in case that there is more attributes defined after) + int pos_next_closing_bracket = str_pos('}', json + colon_pos + 1, 1); + int pos_next_comma = str_pos(',', json + colon_pos + 1, 1); + + //default we assume that the length of value is until the closing bracket + int value_length = (colon_pos + (pos_next_closing_bracket)) - (colon_pos) - 2; + + //string ? + int first_quote = str_pos('"', json + colon_pos, 1); + int second_quote = str_pos('"', json + colon_pos, 2); + + //but we found a comma + if (-1 != pos_next_comma) { + //first found comma comes first than the closing bracket ? + if (pos_next_comma < pos_next_closing_bracket) + value_length = (colon_pos + (pos_next_comma)) - (colon_pos) - 2; + else + value_length = (colon_pos + (pos_next_closing_bracket)) - (colon_pos) - 2; + } + + if (value_length >= 0) { + char* value = malloc(value_length + 1); + strncpy(value, json + colon_pos + 2, value_length); + value[value_length] = '\0'; + + if (-1 != first_quote && -1 != second_quote) { + attr_type = TYPE_STRING; + } else if (NULL != strstr(value, "false") || NULL != strstr(value, "true")) { + attr_type = TYPE_BOOLEAN; + } else if (-1 != atoi(value)) { + attr_type = TYPE_INTEGER; + } else if(NULL != strstr(value, "null")) { + printf("NULL Object !! \n"); + attr_type = TYPE_OBJECT; + } + + printf("value : %s length : %d \n", value, value_length); + + free(value); + } + } + break; + } + return attr_type; +} + +int already_wrote_attribute(char* attribute_name, char attributes[MAX_ATTRIBUTES][MAX_ATTRIBUTE_NAME_LENGTH], int nr_attributes) { + int i; + for (i = 0; i < nr_attributes; ++i) { + if (strcmp(attribute_name, attributes[i]) == 0) + return 1; + } + + return 0; +} + +int find_pos_end_object_array(char *json) +{ + int opening_square_brackets = 1; + int closing_square_brackets = 0; + + char c; + int i; + for (i = 0; i < strlen(json); ++i) { + c = json[i]; + switch (c) { + case '[': + opening_square_brackets++; + break; + case ']': { + closing_square_brackets++; + if (opening_square_brackets == closing_square_brackets) { + return i; + } + } + break; + default: + continue; + break; + } + } + return -1; +} diff --git a/clever_models.h b/clever_models.h new file mode 100644 index 0000000..21a0814 --- /dev/null +++ b/clever_models.h @@ -0,0 +1,32 @@ +// +// clever_models.h +// CleverModels +// +// Created by Bruno Martins on 3/27/12. +// Copyright (c) 2012. All rights reserved. +// + +#ifndef CleverModels_clever_models_h +#define CleverModels_clever_models_h + +#include +#include +#include +#include "constants.h" + +const static int TYPE_OBJECT = 0; +const static int TYPE_LIST = 1; +const static int TYPE_INTEGER = 2; +const static int TYPE_BOOLEAN = 3; +const static int TYPE_STRING = 4; +const static int TYPE_OTHER = 5; + +unsigned int write_json_class_model(char name[], char json[], int language_code, char path[], char* class_headers, int multiple_objects); +int get_attribute_type(char json[], int colon_pos); +int already_wrote_attribute(char* attribute_name, char attributes[MAX_ATTRIBUTES][MAX_ATTRIBUTE_NAME_LENGTH], int nr_attributes); + +int pos_end_of_attribute_and_value(char* json, int current_pos); + +int find_pos_end_object_array(char *json); + +#endif diff --git a/constants.h b/constants.h new file mode 100644 index 0000000..da3fe2c --- /dev/null +++ b/constants.h @@ -0,0 +1,14 @@ +/* + * constants.h + * + * Created on: Apr 4, 2012 + * Author: bmartins + */ + +#ifndef CONSTANTS_H_ +#define CONSTANTS_H_ + +#define MAX_ATTRIBUTES 50 +#define MAX_ATTRIBUTE_NAME_LENGTH 100 + +#endif /* CONSTANTS_H_ */ diff --git a/helper_functions.c b/helper_functions.c new file mode 100644 index 0000000..2d10b49 --- /dev/null +++ b/helper_functions.c @@ -0,0 +1,107 @@ +// +// helper_functions.c +// CleverModels +// +// Created by Bruno Martins on 3/27/12. +// Copyright (c) 2012. All rights reserved. +// + +#include +#include +#include +#include +#include "helper_functions.h" + +char* str_plural_to_singular(char str[]) +{ +// long pos_s_char = str_pos_reverse('s', str, strlen(str), 1); +// //to avoid taking away the last S on double S's ending strings. Like : Adress, is still singular. +// long pos_s_second_char = str_pos_reverse('s', str, strlen(str),2); +// +// if (-1 == pos_s_char || pos_s_char == pos_s_second_char+1) +// return str; +// +// long len = strlen(str); +// +// printf("str : %s \n", str); +// +// if(len > 1) +// str[pos_s_char] = '\0'; +// +// printf("after str : %s \n", str); + + return str; +} + +int str_pos(char c, char haystack[], int occurence) +{ + + int times_found = 0; + int i; + for (i=0; i=0; i--) { + if (c == haystack[i]) { + times_found++; + + if (occurence == times_found) + return i; + } + } + return -1; +} + +void str_to_lower(char str []) +{ + int i; + for (i = 0; str[i]; i++) { + str[i] = tolower(str[i]); + } +} + +char find_first_character(char haystack[]) +{ + int i; + for (i = 0; i + +int str_pos(char c, char haystack[], int occurence); +int str_pos_reverse (char c, char haystack[], int start_pos, int occurence); +void str_to_lower(char str []); +char find_first_character(char haystack[]); +char* str_plural_to_singular(char str[]); +char* escape_single_quotes(char* json); + +#endif diff --git a/java/java_model_writer.c b/java/java_model_writer.c new file mode 100644 index 0000000..013bea1 --- /dev/null +++ b/java/java_model_writer.c @@ -0,0 +1,131 @@ +// +// java_model_writer.c +// CleverModels +// +// Created by Bruno Martins on 3/29/12. +// Copyright (c) 2012. All rights reserved. +// + +#include +#include "java_model_writer.h" +#include "../helper_functions.h" +#include "../clever_models.h" + +int32_t java_write_class_header(FILE* fp, char class_name[]) { + int32_t result = -1; + class_name[0] = toupper(class_name[0]); + char* singular_class_name = str_plural_to_singular(class_name); + fprintf(fp, "import java.util.List; \n\n"); + result = fprintf(fp, "public class %s { \n", singular_class_name); + return result; +} + +int32_t java_write_attribute(FILE* fp, char attribute_name[], u_int16_t type) { + u_int32_t result = -1; + + char c = toupper(attribute_name[0]); + + char* object_type_name = malloc(strlen(attribute_name)); + strncpy(object_type_name, attribute_name, strlen(attribute_name)); + object_type_name[strlen(attribute_name)] = '\0'; + + *object_type_name = c; + object_type_name = str_plural_to_singular(object_type_name); + + if (TYPE_OBJECT == type) + result = fprintf(fp, "\tprivate %s %s; \n", object_type_name, + attribute_name); + else if (TYPE_LIST == type) + result = fprintf(fp, "\tprivate List<%s> %s; \n", object_type_name, + attribute_name); + else if (TYPE_INTEGER == type) + result = fprintf(fp, "\tprivate Integer %s; \n", attribute_name); + else if (TYPE_STRING == type) + result = fprintf(fp, "\tprivate String %s; \n", attribute_name); + else if (TYPE_BOOLEAN == type) + result = fprintf(fp, "\tprivate Boolean %s; \n", attribute_name); + else + result = fprintf(fp, "\tprivate String %s; \n", attribute_name); + + + free(object_type_name); + return result; +} + +int java_write_getters(FILE* fp, int nr_attributes, char attributes[50][100], int attr_types[]) { + int i; + for (i = 0; i < nr_attributes; ++i) { + + char* uppercase_attribute_name = malloc(sizeof(attributes[i])); + strncpy(uppercase_attribute_name, attributes[i], sizeof(attributes[i])); + uppercase_attribute_name[strlen(uppercase_attribute_name)] = '\0'; + uppercase_attribute_name[0] = toupper(uppercase_attribute_name[0]); + + char* object_type_name = malloc(sizeof(uppercase_attribute_name)); + strncpy(object_type_name, uppercase_attribute_name, sizeof(uppercase_attribute_name)); + object_type_name[strlen(uppercase_attribute_name)] = '\0'; + + object_type_name = str_plural_to_singular(object_type_name); + + if (TYPE_OBJECT == attr_types[i]) + fprintf(fp, "\n\tpublic %s get%s() { \n", object_type_name, uppercase_attribute_name); + else if (TYPE_LIST == attr_types[i]) + fprintf(fp, "\n\tpublic List<%s> get%s() { \n", object_type_name, uppercase_attribute_name); + else if (TYPE_INTEGER == attr_types[i]) + fprintf(fp, "\n\tpublic Integer get%s() { \n", uppercase_attribute_name); + else if (TYPE_STRING == attr_types[i]) + fprintf(fp, "\n\tpublic String get%s() { \n", uppercase_attribute_name); + else if (TYPE_BOOLEAN == attr_types[i]) + fprintf(fp, "\n\tpublic Boolean get%s() { \n", uppercase_attribute_name); + else + fprintf(fp, "\n\tpublic String get%s() { \n", uppercase_attribute_name); + + + + fprintf(fp, "\t\t return %s; \n", attributes[i]); + fprintf(fp, "\t} \n"); + + free(object_type_name); + free(uppercase_attribute_name); + } + + return i; +} + +int java_write_setters(FILE* fp, int nr_attributes, char attributes[50][100], int attr_types[]) { + int i; + for (i = 0; i < nr_attributes; ++i) { + + char* uppercase_attribute_name = malloc(sizeof(attributes[i])); + strncpy(uppercase_attribute_name, attributes[i], sizeof(attributes[i])); + uppercase_attribute_name[strlen(uppercase_attribute_name)] = '\0'; + uppercase_attribute_name[0] = toupper(uppercase_attribute_name[0]); + + char* object_type_name = malloc(sizeof(uppercase_attribute_name)); + strncpy(object_type_name, uppercase_attribute_name, sizeof(uppercase_attribute_name)); + object_type_name[strlen(uppercase_attribute_name)] = '\0'; + + object_type_name = str_plural_to_singular(object_type_name); + + if (TYPE_OBJECT == attr_types[i]) + fprintf(fp, "\n\tpublic void set%s(%s %s) { \n", uppercase_attribute_name, object_type_name, attributes[i]); + else if (TYPE_LIST == attr_types[i]) + fprintf(fp, "\n\tpublic void set%s(List<%s> %s) { \n", uppercase_attribute_name, object_type_name, attributes[i]); + else if (TYPE_INTEGER == attr_types[i]) + fprintf(fp, "\n\tpublic void set%s(Integer %s) { \n", uppercase_attribute_name, attributes[i]); + else if (TYPE_STRING == attr_types[i]) + fprintf(fp, "\n\tpublic void set%s(String %s) { \n", uppercase_attribute_name, attributes[i]); + else if (TYPE_BOOLEAN == attr_types[i]) + fprintf(fp, "\n\tpublic void set%s(Boolean %s) { \n", uppercase_attribute_name, attributes[i]); + else + fprintf(fp, "\n\tpublic void set%s(String %s) { \n", uppercase_attribute_name, attributes[i]); + + fprintf(fp, "\t\t this.%s = %s; \n", attributes[i], attributes[i]); + fprintf(fp, "\t} \n"); + + free(object_type_name); + free(uppercase_attribute_name); + } + + return i; +} diff --git a/java/java_model_writer.h b/java/java_model_writer.h new file mode 100644 index 0000000..81adc6b --- /dev/null +++ b/java/java_model_writer.h @@ -0,0 +1,21 @@ +// +// java_model_writer.h +// CleverModels +// +// Created by Bruno Martins on 3/29/12. +// Copyright (c) 2012. All rights reserved. +// + +#ifndef CleverModels_java_model_writer_h +#define CleverModels_java_model_writer_h + +#include +#include +#include "../constants.h" + +int32_t java_write_class_header(FILE* fp, char class_name[]); +int32_t java_write_attribute(FILE* fp, char attribute_name[], u_int16_t type); +int java_write_getters(FILE* fp, int nr_attributes, char attributes[MAX_ATTRIBUTES][MAX_ATTRIBUTE_NAME_LENGTH], int attr_types[]); +int java_write_setters(FILE* fp, int nr_attributes, char attributes[MAX_ATTRIBUTES][MAX_ATTRIBUTE_NAME_LENGTH], int attr_types[]); + +#endif diff --git a/languages.c b/languages.c new file mode 100644 index 0000000..02a899d --- /dev/null +++ b/languages.c @@ -0,0 +1,35 @@ +// +// languages.c +// CleverModels +// +// Created by Bruno Martins on 3/29/12. +// Copyright (c) 2012. All rights reserved. +// + +#include +#include +#include "helper_functions.h" +#include "languages.h" + +int get_language_code(char* language) +{ + int code = -1; + + if (strcmp(language, "java") == 0) { + code = JAVA; + } + + if (strcmp(language, "php") == 0) { + code = PHP; + } + + if (strcmp(language, "csharp") == 0) { + code = CSHARP; + } + + if (strcmp(language, "cpp") == 0) { + code = CPP; + } + + return code; +} diff --git a/languages.h b/languages.h new file mode 100644 index 0000000..52aa804 --- /dev/null +++ b/languages.h @@ -0,0 +1,21 @@ +// +// languages.h +// CleverModels +// +// Created by Bruno Martins on 3/29/12. +// Copyright (c) 2012. All rights reserved. +// + +#ifndef CleverModels_languages_h +#define CleverModels_languages_h + +#include + +const static int JAVA = 0; +const static int PHP = 1; +const static int CSHARP = 2; +const static int CPP = 3; + +int get_language_code(char* language); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..ae42cee --- /dev/null +++ b/main.c @@ -0,0 +1,133 @@ +// +// main.c +// CleverModels +// +// Created by Bruno Martins on 3/20/12. +// Copyright (c) 2012. All rights reserved. +// + +#include +#include "clever_models.h" +#include +#include "languages.h" +#include +#include +#include "helper_functions.h" + + +int main(int argc, char * argv[]) { + + int as_model_path = 0; + int as_name = 0; + int as_language = 0; + int as_url = 0; + int as_class_header = 0; + int as_json_string = 0; + + char* feed_string_file = "/tmp/clevermodels_http_response_body"; + + char* models_path = 0; + char* name = 0; + char* json = malloc(1024*8); + char* class_headers = 0; + + int language_code = -1; + + int c; + int pid; + + opterr = 0; + + while ((c = getopt(argc, argv, "u:l:n:p:h:j:")) != -1) { + switch (c) { + case 'u': { + as_url = 1; + pid = fork(); + + if (0 == pid) { + execl("/usr/bin/curl", "curl", "-o", feed_string_file, optarg, NULL); + + //printf(" exec return : %d \n", r); + return 0; + } + } + break; + case 'l': { + as_language = 1; + language_code = get_language_code(optarg); + if (-1 == language_code) { + printf("unknown language : %s \n", optarg); + exit(-1); + } + } + break; + case 'n': { + as_name = 1; + name = optarg; + } + break; + case 'p': { + as_model_path = 1; + models_path = optarg; + } + break; + case 'h': { + as_class_header = 1; + class_headers = optarg; + } + break; + case 'j': { + as_json_string = 1; + json = optarg; + } + break; + case '?': + if (optopt == 'c') + fprintf(stderr, "Option -%c requires an argument.\n", optopt); + else if (isprint(optopt)) + fprintf(stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt); + //return 1; + break; + default: + //abort(); + break; + } + } + //wait for curl to finish requesting the feed + wait(&pid); + + system("cat /tmp/clevermodels_http_response_body | sed \"s/'//g\" -i /tmp/clevermodels_http_response_body"); + + if (0 == as_model_path || 0 == as_name || 0 == as_language) { + perror("missing arguments! Required -n -l -p"); + exit(-1); + } +// + if (0 == as_json_string) { + FILE* feed_file_stream; + feed_file_stream = fopen(feed_string_file, "r"); + char ch; + while ((ch = fgetc(feed_file_stream)) != EOF) { + json[strlen(json)] = ch; + } + + //fclose(feed_file_stream); + } +// + printf("json : %s \n", json); + + //json = clean_spaces(json); + + json[strlen(json)] = '\0'; + + + + write_json_class_model(name, json, language_code, models_path, class_headers, 0); + free(json); + + return 0; +} + + diff --git a/model_builder.c b/model_builder.c new file mode 100644 index 0000000..7497728 --- /dev/null +++ b/model_builder.c @@ -0,0 +1,87 @@ +// +// model_builder.c +// CleverModels +// +// Created by Bruno Martins on 3/29/12. +// Copyright (c) 2012. All rights reserved. +// + +#include +#include +#include "languages.h" +#include "model_builder.h" +#include "clever_models.h" +#include "helper_functions.h" +#include "java/java_model_writer.h" + +int write_setters(FILE* implementation_file, FILE* header_file, int language_code, char attributes[MAX_ATTRIBUTES][MAX_ATTRIBUTE_NAME_LENGTH], int attr_types[], int nr_attributes) +{ + int result = -1; + if (JAVA == language_code) { + result = java_write_setters(implementation_file, nr_attributes, attributes, attr_types); + } + return result; +} + +int write_getters(FILE* implementation_file, FILE* header_file, int language_code, char attributes[MAX_ATTRIBUTES][MAX_ATTRIBUTE_NAME_LENGTH], int attr_types[], int nr_attributes) +{ + int result = -1; + if (JAVA == language_code) { + result = java_write_getters(implementation_file, nr_attributes, attributes, attr_types); + } + return result; +} + +int write_class_header(char class_name[], int16_t language, FILE* implementation_file, FILE* header_file) { + int result = -1; + + if (JAVA == language) + result = java_write_class_header(implementation_file, class_name); + + return result; +} + +int write_attribute(char attribute_name[], int16_t type, int16_t language, + FILE* implementation_file, FILE* header_file) { + + int result = -1; + + if (JAVA == language) { + + result = java_write_attribute(implementation_file, attribute_name, + type); + } + + return result; +} + +void create_class_files(char name[], char path[], int language_code, char class_headers[] , FILE** implementation, FILE** header) { + char file_path[255]; + strcpy(file_path, path); + + name[0] = toupper(name[0]); + char* singular_class_name = str_plural_to_singular(name); + + strcat(file_path, singular_class_name); + strcat(file_path, "."); + + if (JAVA == language_code) { + strcat(file_path, "java"); + } + + *implementation = fopen(file_path, "w+"); + + if (NULL == *implementation) { + perror("failed creating implementation file \n"); + exit(-1); + } + + header = NULL; + + fprintf(*implementation, "// Class generated by Clever Models \n"); + if (0 != class_headers) { + fprintf(*implementation, "%s\n\n", class_headers); + } +} + + diff --git a/model_builder.h b/model_builder.h new file mode 100644 index 0000000..f4ed34f --- /dev/null +++ b/model_builder.h @@ -0,0 +1,23 @@ +// +// model_builder.h +// CleverModels +// +// Created by Bruno Martins on 3/29/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef CleverModels_model_builder_h +#define CleverModels_model_builder_h + +#include +#include +#include +#include "constants.h" + +int write_setters(FILE* implementation_file, FILE* header_file, int language_code, char attributes[MAX_ATTRIBUTES][MAX_ATTRIBUTE_NAME_LENGTH], int attr_types[], int nr_attributes); +int write_getters(FILE* implementation_file, FILE* header_file, int language_code, char attributes[MAX_ATTRIBUTES][MAX_ATTRIBUTE_NAME_LENGTH], int attr_types[], int nr_attributes); +int write_class_header(char class_name[], int16_t language, FILE* implementation_file, FILE* header_file); +int write_attribute(char attribute_name[], int16_t type, int16_t language, FILE* implementation_file, FILE* header_file); +void create_class_files(char name[], char path[], int language_code, char class_headers[], FILE** implementation, FILE** header); + +#endif