/* Copyright(C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum COMPONENT_TYPE { COMPOSITE ,LEAF };
void indent(int n);
struct Component;
/* ComponentList */
struct ComponentList {
struct Component* component_;
struct ComponentList* next_;
};
struct ComponentList* New_ComponentList(struct Component* component);
void Delete_ComponentList(struct ComponentList* list);
/* Component Interface */
struct Component {
enum COMPONENT_TYPE type_;
char* data_;
struct ComponentList* child_top_;
struct ComponentList* child_last_;
void (*add)(struct Component* pthis ,struct Component* child);
void (*Operation)(struct Component* pthis ,int n);
};
struct Component* New_Component(enum COMPONENT_TYPE type ,char* data);
void Delete_Component(struct Component* comp);
void Leaf_add(struct Component* pthis ,struct Component* child);
void Leaf_Operation(struct Component* pthis ,int n);
void Composite_add(struct Component* pthis ,struct Component* child);
void Composite_Operation(struct Component* pthis ,int n);
/* ComponentList Implementation */
struct ComponentList* New_ComponentList(struct Component* component) {
struct ComponentList* list = NULL;
list = (struct ComponentList*)malloc(sizeof(struct Component));
list->component_ = component;
list->next_ = NULL;
return list;
}
void Delete_ComponentList(struct ComponentList* list) {
struct ComponentList* cur = NULL;
struct ComponentList* tmp = NULL;
if (list == NULL) {
return;
}
cur = list;
while (cur != NULL) {
tmp = cur->next_;
free(cur);
cur = tmp;
}
return;
}
/* Component Class Implementation */
struct Component* New_Component(enum COMPONENT_TYPE type ,char* data) {
struct Component* component = NULL;
char* buf = NULL;
component = (struct Component*)malloc(sizeof(struct Component));
buf = (char*)malloc(strlen(data)+1);
strcpy(buf ,data);
component->type_ = type;
component->data_ = buf;
component->child_top_ = NULL;
component->child_last_ = NULL;
switch (type) {
case LEAF:
component->add = &Leaf_add;
component->Operation = &Leaf_Operation;
break;
case COMPOSITE:
component->add = &Composite_add;
component->Operation = &Composite_Operation;
break;
}
return component;
}
void Delete_Component(struct Component* component) {
struct ComponentList* cur = NULL;
struct ComponentList* tmp = NULL;
if (component == NULL) {
return;
}
free(component->data_);
component->data_ = NULL;
if (component->type_ == COMPOSITE) {
cur = component->child_top_;
while (cur != NULL) {
tmp = cur->next_;
Delete_Component(cur->component_);
cur = tmp;
}
}
Delete_ComponentList(component->child_top_);
free(component);
component = NULL;
return;
}
void Leaf_add(struct Component* pthis ,struct Component* child) {
return; /* No operation */
}
void Leaf_Operation(struct Component* pthis ,int n) {
indent(n);
printf("Leaf:%s\n" ,pthis->data_);
return;
}
void Composite_add(struct Component* pthis ,struct Component* child) {
struct Component* cur = NULL;
struct ComponentList* list = NULL;
list = New_ComponentList(child);
if (pthis->child_top_ == NULL) {
pthis->child_top_ = list;
pthis->child_last_ = list;
} else {
pthis->child_last_->next_ = list;
pthis->child_last_ = list;
}
return;
}
void Composite_Operation(struct Component* pthis ,int n) {
struct Component* component = NULL;
struct ComponentList* cur = NULL;
indent(n);
printf("Composite:%s\n" ,pthis->data_);
cur = pthis->child_top_;
while (cur != NULL) {
++n;
component = cur->component_;
component->Operation(component, n);
--n;
cur = cur->next_;
}
return;
}
/* Utility Function */
void indent(int n) {
while (n != 0) {
printf(" ");
--n;
}
return;
}
/* Facade Implementation */
struct Component* gComponentRoot = NULL;
struct ComponentList* gCompositeListTop = NULL;
struct ComponentList* gCompositeListLast = NULL;
struct ComponentList* gLeafListTop = NULL;
struct ComponentList* gLeafListLast = NULL;
void Facade_private_CompositeList_add(struct Component* component) {
struct ComponentList* list = New_ComponentList(component);
if (gCompositeListTop == NULL) {
gCompositeListTop = list;
gCompositeListLast = list;
} else {
gCompositeListLast->next_ = list;
gCompositeListLast = list;
}
return;
}
void Facade_private_LeafList_add(struct Component* leaf) {
struct ComponentList* list = New_ComponentList(leaf);
if (gLeafListTop == NULL) {
gLeafListTop = list;
gLeafListLast = list;
} else {
gLeafListLast->next_ = list;
gLeafListLast = list;
}
return;
}
struct ComponentList* Facade_private_CopyComponentList(struct ComponentList* list) {
struct ComponentList* copy = NULL;
struct ComponentList* top = NULL;
top = New_ComponentList(list->component_);
top->next_ = list->next_;
list = list->next_;
while (list != NULL) {
copy = New_ComponentList(list->component_);
copy->next_ = list->next_;
list = list->next_;
}
return top;
}
void Facade_BuildTree() {
struct Component* composit1 = NULL;
struct Component* leaf1_1 = NULL;
struct Component* leaf1_2 = NULL;
struct Component* composit2 = NULL;
struct Component* leaf2_1 = NULL;
struct Component* leaf2_2 = NULL;
composit1 = New_Component(COMPOSITE ,"Root");
Facade_private_CompositeList_add(composit1);
leaf1_1 = New_Component(LEAF ,"File1");
Facade_private_LeafList_add(leaf1_1);
leaf1_2 = New_Component(LEAF ,"File2");
Facade_private_LeafList_add(leaf1_2);
composit1->add(composit1 ,leaf1_1);
composit1->add(composit1 ,leaf1_2);
composit2 = New_Component(COMPOSITE ,"Folder");
Facade_private_CompositeList_add(composit2);
leaf2_1 = New_Component(LEAF ,"File3");
Facade_private_LeafList_add(leaf2_1);
leaf2_2 = New_Component(LEAF ,"File4");
Facade_private_LeafList_add(leaf2_2);
composit2->add(composit2 ,leaf2_1);
composit2->add(composit2 ,leaf2_2);
composit1->add(composit1 ,composit2);
gComponentRoot = composit1;
return;
}
struct ComponentList* Facade_GetComponentById(const char* id) {
struct ComponentList* list = NULL;
struct ComponentList* new_top = NULL;
struct ComponentList* new_last = NULL;
list = gCompositeListTop;
while (list != NULL) {
if (strstr(list->component_->data_, id) != NULL) {
break;
}
list = list->next_;
}
if (list != NULL) {
if (new_top == NULL) {
new_top = New_ComponentList(list->component_);
new_last = new_top;
} else {
new_last->next_ = New_ComponentList(list->component_);
new_last = new_last->next_;
}
}
list = gLeafListTop;
while (list != NULL) {
if (strstr (list->component_->data_, id) != NULL) {
break;
}
list = list->next_;
}
if (list != NULL) {
if (new_top == NULL) {
new_top = New_ComponentList(list->component_);
new_last = new_top;
} else {
new_last->next_ = New_ComponentList(list->component_);
new_last = new_last->next_;
}
}
return new_top;
}
struct ComponentList* Facade_GetComponentByType(enum COMPONENT_TYPE type) {
struct ComponentList* list = NULL;
if (type == COMPOSITE) {
return Facade_private_CopyComponentList(gCompositeListTop);
} else if (type == LEAF) {
return Facade_private_CopyComponentList(gLeafListTop);
}
return NULL;
}
void Facade_DeleteTree() {
Delete_ComponentList(gCompositeListTop);
Delete_ComponentList(gLeafListTop);
Delete_Component(gComponentRoot);
return;
}
int main() {
struct ComponentList* list = NULL;
struct Component* component = NULL;
Facade_BuildTree();
printf("** get File3 Component **\n");
list = Facade_GetComponentById("File3");
component = list->component_;
component->Operation(component ,0);
Delete_ComponentList(list);
printf("** get Folder Component **\n");
list = Facade_GetComponentById("Folder");
component = list->component_;
component->Operation(component ,0);
Delete_ComponentList(list);
printf("** list Leaf Component **\n");
list = Facade_GetComponentByType(LEAF);
while (list != NULL) {
component = list->component_;
component->Operation(component ,0);
list = list->next_;
}
Delete_ComponentList(list);
printf("** list Composite Component **\n");
list = Facade_GetComponentByType(COMPOSITE);
while (list != NULL) {
component = list->component_;
component->Operation(component ,0);
list = list->next_;
}
Delete_ComponentList(list);
Facade_DeleteTree();
return 0;
}
|