Hi,

I did a quick hack to populate the information for a class from a 
java file. It almost certainly leaks memory as i haven't done C in
years but it does the trick for me. I've attached a patch for my 
changes. 

Hope its use for someone.

Fin.
--
Common subdirectories: fii/dia/objects/UML/CVS and dia/objects/UML/CVS
diff -NU3 fii/dia/objects/UML/class.h dia/objects/UML/class.h
--- fii/dia/objects/UML/class.h Tue Jan  2 21:09:48 2001
+++ dia/objects/UML/class.h     Tue Feb 27 22:41:17 2001
@@ -27,6 +27,7 @@
 
 typedef struct _UMLClass UMLClass;
 typedef struct _UMLClassDialog UMLClassDialog;
+typedef struct _UMLClassState UMLClassState;
 
 struct _UMLClass {
   Element element;
@@ -94,6 +95,7 @@
   GtkToggleButton *attr_supp;
   GtkToggleButton *op_vis;
   GtkToggleButton *op_supp;
+  GtkFileSelection *file_sel;
   DiaColorSelector *fg_color;
   DiaColorSelector *bg_color;
 
@@ -134,6 +136,26 @@
   GtkToggleButton *templ_template;
   GtkEntry *templ_name;
   GtkEntry *templ_type;
+};
+
+struct _UMLClassState {
+  char *name;
+  char *stereotype;
+  int abstract;
+  int suppress_attributes;
+  int suppress_operations;
+  int visible_attributes;
+  int visible_operations;
+
+  /* Attributes: */
+  GList *attributes;
+
+  /* Operators: */
+  GList *operations;
+
+  /* Template: */
+  int template;
+  GList *formal_params;
 };
 
 extern GtkWidget *umlclass_get_properties(UMLClass *umlclass);
diff -NU3 fii/dia/objects/UML/class_dialog.c dia/objects/UML/class_dialog.c
--- fii/dia/objects/UML/class_dialog.c  Thu Mar  1 14:02:17 2001
+++ dia/objects/UML/class_dialog.c      Wed Feb 28 16:20:47 2001
@@ -24,13 +24,17 @@
 #include <gtk/gtk.h>
 #include <math.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <glib.h>
 
 #include "config.h"
 #include "object.h"
 #include "objchange.h"
 #include "intl.h"
 #include "class.h"
-
+#include "parse.h"
 
 typedef struct _Disconnect {
   ConnectionPoint *cp;
@@ -38,29 +42,6 @@
   Handle *other_handle;
 } Disconnect;
 
-typedef struct _UMLClassState UMLClassState;
-
-struct _UMLClassState {
-  char *name;
-  char *stereotype;
-  int abstract;
-  int suppress_attributes;
-  int suppress_operations;
-  int visible_attributes;
-  int visible_operations;
-
-  /* Attributes: */
-  GList *attributes;
-
-  /* Operators: */
-  GList *operations;
-
-  /* Template: */
-  int template;
-  GList *formal_params;
-};
-
-
 typedef struct _UMLClassChange UMLClassChange;
 
 struct _UMLClassChange {
@@ -81,6 +62,8 @@
 static ObjectChange *new_umlclass_change(UMLClass *obj, UMLClassState *saved_state,
                                         GList *added, GList *deleted,
                                         GList *disconnected);
+static void attribute_list_item_destroy_callback(GtkWidget *list_item, gpointer data);
+static void operations_list_item_destroy_callback(GtkWidget *list_item, gpointer 
+data);
 
 /**** Utility functions ******/
 static void
@@ -162,6 +145,123 @@
   dia_color_selector_set_color(prop_dialog->bg_color, &umlclass->color_background);
 }
 
+static void
+state_fill_in_dialog(UMLClassState *state, UMLClassDialog *prop_dialog)
+{
+  if (state->name != NULL) 
+    gtk_entry_set_text(prop_dialog->classname, state->name);
+  else 
+    gtk_entry_set_text(prop_dialog->classname, "");
+
+  if (state->stereotype != NULL)
+    gtk_entry_set_text(prop_dialog->stereotype, state->stereotype);
+  else 
+    gtk_entry_set_text(prop_dialog->stereotype, "");
+
+  gtk_toggle_button_set_active(prop_dialog->abstract_class, state->abstract);
+  gtk_toggle_button_set_active(prop_dialog->attr_vis, state->visible_attributes);
+  gtk_toggle_button_set_active(prop_dialog->op_vis, state->visible_operations);
+  gtk_toggle_button_set_active(prop_dialog->attr_supp, state->suppress_attributes);
+  gtk_toggle_button_set_active(prop_dialog->op_supp, state->suppress_operations);
+}
+
+static void 
+file_dialog_show(GtkButton *butt, GtkWidget *file_dialog)
+{
+  gtk_widget_show(file_dialog);
+}
+
+static void 
+file_dialog_cancel(GtkButton *butt, GtkWidget *file_dialog)
+{
+  gtk_widget_hide(file_dialog);
+}
+
+static void
+op_add(UMLOperation *op,UMLClass *umlclass)
+{
+  GList *list;
+  UMLClassDialog *prop_dialog;
+  GtkWidget *list_item;
+  char *str;
+
+  prop_dialog = umlclass->properties_dialog;
+
+  str = uml_get_operation_string(op);
+  list_item = gtk_list_item_new_with_label(str);
+  gtk_widget_show(list_item);
+  g_free(str);
+
+  gtk_object_set_user_data(GTK_OBJECT(list_item), op);
+  gtk_signal_connect (GTK_OBJECT (list_item), "destroy",
+                     GTK_SIGNAL_FUNC (operations_list_item_destroy_callback),
+                     NULL);
+  
+  list = g_list_append(NULL, list_item);
+  gtk_list_append_items(prop_dialog->operations_list, list);
+}
+
+static void
+at_add(UMLAttribute *attr,UMLClass *umlclass)
+{
+  GList *list;
+  UMLClassDialog *prop_dialog;
+  GtkWidget *list_item;
+  char *str;
+
+  prop_dialog = umlclass->properties_dialog;
+
+  str = uml_get_attribute_string(attr);
+  list_item = gtk_list_item_new_with_label(str);
+
+  gtk_widget_show(list_item);
+  g_free(str);
+
+  gtk_object_set_user_data(GTK_OBJECT(list_item), attr);
+  gtk_signal_connect (GTK_OBJECT (list_item), "destroy",
+                     GTK_SIGNAL_FUNC (attribute_list_item_destroy_callback),
+                     NULL);
+  
+  list = g_list_append(NULL, list_item);
+  gtk_list_append_items(prop_dialog->attributes_list, list);
+}
+
+static void 
+file_dialog_ok(GtkButton *butt, UMLClass *umlclass)
+{
+  UMLClassState state;
+  gchar *filename;
+  int file;
+
+  filename = gtk_file_selection_get_filename(umlclass->properties_dialog->file_sel);
+  file = open(filename, O_RDONLY, NULL);
+  if(file == -1){
+    g_print("Could not open %s\n",filename);
+    return;
+  }
+
+  gtk_widget_hide(GTK_WIDGET(umlclass->properties_dialog->file_sel));  
+
+  state.name=NULL;
+  state.stereotype=NULL;
+  state.abstract=0;
+  state.suppress_attributes=0;
+  state.suppress_operations=0;
+  state.visible_attributes=1;
+  state.visible_operations=1;
+  state.attributes=NULL;
+  state.operations=NULL;
+  state.template=0;
+  state.formal_params=NULL;
+  if(scan_file(filename, file, &state)){
+    state_fill_in_dialog(&state,umlclass->properties_dialog);
+    g_list_foreach(state.operations, &op_add, (gpointer)umlclass);
+    g_list_foreach(state.attributes, &at_add, (gpointer)umlclass);
+  }
+  /* tidy up memory */
+}  
+
+
 static void 
 class_create_page(GtkNotebook *notebook,  UMLClass *umlclass)
 {
@@ -174,6 +274,7 @@
   GtkWidget *checkbox;
   GtkWidget *color_background;
   GtkWidget *color_foreground;
+  GtkWidget *file_button;
 
   prop_dialog = umlclass->properties_dialog;
 
@@ -255,6 +356,21 @@
   dia_color_selector_set_color((DiaColorSelector *)color_background, 
&umlclass->color_background);
   prop_dialog->bg_color = (DiaColorSelector *)color_background;
   gtk_box_pack_end( GTK_BOX(hbox), color_background, TRUE, TRUE,0);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
+
+  hbox = gtk_hbox_new(FALSE, 5);
+  label = gtk_label_new(_("Reverse engineer class"));
+  gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+  gtk_box_pack_start( GTK_BOX(hbox), label, TRUE, TRUE, 0);
+  file_button = gtk_button_new_with_label(_("Select File"));
+  prop_dialog->file_sel = GTK_FILE_SELECTION(gtk_file_selection_new(_("Reverse 
+Engineer Class")));
+  gtk_signal_connect ( GTK_OBJECT (prop_dialog->file_sel->cancel_button), "clicked", 
+                      &file_dialog_cancel, prop_dialog->file_sel);
+  gtk_signal_connect ( GTK_OBJECT (prop_dialog->file_sel->ok_button), "clicked", 
+                      &file_dialog_ok, umlclass);
+  gtk_signal_connect ( GTK_OBJECT (file_button), "clicked", 
+                      &file_dialog_show, prop_dialog->file_sel);
+  gtk_box_pack_end( GTK_BOX(hbox), file_button, TRUE, TRUE,0);
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
 
   gtk_widget_show_all (vbox);
diff -NU3 fii/dia/objects/UML/parse.c dia/objects/UML/parse.c
--- fii/dia/objects/UML/parse.c Thu Jan  1 01:00:00 1970
+++ dia/objects/UML/parse.c     Wed Feb 28 15:53:07 2001
@@ -0,0 +1,229 @@
+#include <gtk/gtk.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <glib.h>
+
+#include "intl.h" 
+/*  #include "class.h"*/
+#include "parse.h"
+
+static int nsymbols = 10;
+static char* symbol[] = {"public","private","protected","abstract","class",
+                         "interface","static","extends","implements","throws"};
+
+static void
+add_operation(UMLClassState *state, UMLVisibility visibility, gchar *type, 
+             gchar *name, gboolean is_static, gboolean abstract)
+{
+  UMLOperation *op=uml_operation_new();
+
+  g_print("Adding operation: %d %s %s\n", visibility, type, name);
+  op->name = name;
+  op->type = type;
+  op->visibility=visibility;
+  if(is_static)
+    op->class_scope = 1;
+  if(abstract)
+    op->abstract = 1;
+
+  state->operations = g_list_append(state->operations, op);
+}
+
+static void
+add_attribute(UMLClassState *state, UMLVisibility visibility, gchar *type, 
+             gchar *name, gboolean is_static)
+{
+  UMLAttribute *at=uml_attribute_new();
+
+  g_print("Adding parameter: %d %s %s\n", visibility, type, name);
+  at->name = name;
+  at->type = type;
+  at->visibility=visibility;
+  if(is_static)
+    at->class_scope = 1;
+
+  state->attributes = g_list_append(state->attributes, at);
+}
+
+static GScanner* 
+get_scanner(int file)
+{
+  GScanner *scanner;
+  int i;
+
+  scanner = g_scanner_new(NULL);
+  scanner->config->cset_identifier_nth = g_strjoin(NULL, 
+scanner->config->cset_identifier_nth, 
+                                                  _("."), NULL);
+
+  for(i=0;i<nsymbols; i++)
+    g_scanner_scope_add_symbol(scanner, 0, _(symbol[i]), _(symbol[i]));
+
+  g_scanner_input_file(scanner, file);
+
+  return scanner;
+}
+
+
+/**
+ * Simplified java grammar
+ *
+ * FILE := [ HEADER ]* ( CLASS | INTERFACE )
+ * HEADER := id* ;
+ * CLASS := [abstract] [(public | protected | private)] class id [extends id] 
+[implements id [,id]*] { CLASSBODY }
+ * INTERFACE := [public] interface id [extends id] { INTERFACEBODY }
+ * CLASSBODY := [(VAR | METHOD | CONSTRUCTOR | INITIALISER)] CLASSBODY
+ * VAR := [(public | protected | private)] id id;
+ * METHOD := [abstract] [synchronized] [static] [(public | protected | private)] id 
+id ( [ PARAMS ] ) [ throws id [,id]* ] { don't care }
+ * CONSTRUCTOR := [(public | protected | private)] id ( [ PARAMS ] ) [ throws id 
+[,id]* ] { don't care }
+ * INITIALISER := [static] { don't care }
+ * INTERFACEBODY := [synchronized] [(public | protected | private)] id id ( [ PARAMS 
+] ) [ throws id [,id]* ] ; INTERFACEBODY
+ *
+ */
+static int 
+parse_java_file(int file, UMLClassState *state)
+{
+  GTokenType tokentype;
+  gchar *name=NULL;
+  int depth=0,depth2=0;
+  gboolean expectingClass=FALSE;
+  gboolean expectingType=FALSE;
+  gboolean expectingOperation=FALSE;
+  gboolean expectingParams=FALSE;
+  gboolean interface=FALSE;
+  gboolean abstract=FALSE;
+  gboolean is_static=FALSE;
+
+  UMLVisibility visibility=UML_IMPLEMENTATION;
+  gchar *type=NULL;
+
+  GScanner *scanner=get_scanner(file);
+
+  while((tokentype = g_scanner_get_next_token(scanner))!= G_TOKEN_EOF){
+    GTokenValue gtv = g_scanner_cur_value(scanner);
+    switch(tokentype){
+    case G_TOKEN_LEFT_CURLY: 
+      depth++; 
+      if(depth < 2){
+       expectingType=TRUE;
+      }
+      if(expectingParams){
+       if(type != NULL && name != NULL)
+         add_operation(state, visibility, type, name, is_static, abstract);
+      }
+
+      type=NULL;
+      name=NULL;
+      expectingOperation=FALSE;
+      expectingParams=FALSE;
+      abstract=FALSE;
+      is_static=FALSE;
+      visibility=UML_IMPLEMENTATION;
+      break;
+    case G_TOKEN_RIGHT_CURLY: 
+      depth--; 
+      break;
+    case G_TOKEN_LEFT_PAREN:
+      depth2++;
+      break;
+    case G_TOKEN_RIGHT_PAREN:
+      depth2--;
+      break;
+    case ';':
+      if(depth == 1){
+       expectingType=TRUE;
+       expectingOperation=FALSE;
+       expectingParams=FALSE;
+
+       if(type != NULL && name != NULL){
+         if(interface)
+           add_operation(state, visibility, type, name, is_static, abstract);
+         else
+           add_attribute(state, visibility, type, name, is_static);
+       }
+      } else if(depth == 0){
+       expectingType=FALSE;
+       expectingOperation=FALSE;
+       expectingParams=FALSE;
+      }
+
+      type=NULL;
+      name=NULL;
+      abstract=FALSE;
+      is_static=FALSE;
+      visibility=UML_IMPLEMENTATION;
+
+      break;
+    case G_TOKEN_IDENTIFIER:
+       if(depth < 2 && depth2 < 1)
+       {
+           if(expectingClass){
+               state->name = strdup(gtv.v_identifier);
+               expectingClass=FALSE;   
+           }
+           if(expectingType){
+               type = g_strdup(gtv.v_identifier);
+               
+               expectingOperation=TRUE;
+               expectingType=FALSE;
+           } else if(expectingOperation){
+               name = g_strdup(gtv.v_identifier);
+               
+               expectingOperation=FALSE;
+               expectingType=FALSE;
+               expectingParams=TRUE;
+           }
+       }
+       break;
+    case G_TOKEN_SYMBOL:
+      if(depth < 1){
+       if(strcmp(gtv.v_symbol, _("abstract"))==0){
+         state->abstract=1;
+       }
+       if(strcmp(gtv.v_symbol, _("interface"))==0){
+         state->stereotype = strdup("interface");
+         state->visible_attributes=0;
+         expectingClass=TRUE;
+         interface=TRUE;
+         visibility = UML_PUBLIC;
+       }
+       if(strcmp(gtv.v_symbol, _("class"))==0){
+         state->stereotype = strdup("");
+         expectingClass=TRUE;
+       }       
+      } else if(depth < 2) {
+       if(strcmp(gtv.v_symbol, _("public"))==0) {
+         expectingType = TRUE;
+         visibility = UML_PUBLIC;
+       }
+       if(strcmp(gtv.v_symbol, _("protected"))==0) {
+         expectingType = TRUE;
+         visibility = UML_PROTECTED;
+       }
+       if(strcmp(gtv.v_symbol, _("private"))==0) {
+         expectingType = TRUE;
+         visibility = UML_PRIVATE;
+       }
+       if(strcmp(gtv.v_symbol, _("static"))==0) {
+         is_static = TRUE;
+       }
+       if(strcmp(gtv.v_symbol, _("abstract"))==0) {
+         abstract = TRUE;
+       }
+      }
+    default:
+    }
+  }
+  g_scanner_destroy(scanner);
+  g_print("Finished scanning file\n");
+  return 1;
+}
+
+extern int scan_file(gchar* filename, int file, UMLClassState *state)
+{  
+  if(strstr(filename, ".java") != NULL)
+    return parse_java_file(file, state);
+
+  return 0;
+}
diff -NU3 fii/dia/objects/UML/parse.h dia/objects/UML/parse.h
--- fii/dia/objects/UML/parse.h Thu Jan  1 01:00:00 1970
+++ dia/objects/UML/parse.h     Wed Feb 28 15:53:19 2001
@@ -0,0 +1,26 @@
+/* Dia -- an diagram creation/manipulation program
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PARSE_H
+#define PARSE_H
+
+#include "class.h"
+
+extern int scan_file(gchar *filename, int file, UMLClassState *state);
+
+#endif /* PARSE_H */
+
Common subdirectories: fii/dia/objects/UML/pixmaps and dia/objects/UML/pixmaps

Reply via email to