Atomic Domains of Java Library Classes Hisham M. Haddad, Woranuch Kaensaksiri, and Arjun Vasudevan CSIS Department Kennesaw State University Kennesaw, Georgia 30144 Abstract - Component reuse is evolving technology that is facing some challenges. One issue is the ease of reuse and the need for reuse solutions that facilitate self-selection of reusable components. This work builds on the “Atomic Domains and Wrappers” framework model that promotes highly reusable domain-specific software components. Through illustrative applications, the framework is applied to Java library classes to demonstrate the use of atomic domains to achieve effective component reuse. This work in an effort to facilitate software reuse and minimize coding effort when using library components organized into cohesive atomic domains. This work is a contribution to component-based development. the atomic domain. Each atomic domain is associated with a command that is referenced in the application source code. The command refers to all components within the respective atomic domain. The command does not act as a single library call or an overloaded function. The atomic domain components are hidden from the developer and can only be referenced by the wrapper manager. When the command is used in the developer’s source code, the compiler supplies all required data to the wrapper manager through the wrapper’s API. The wrapper manager evaluates the command at the point it is used in the application source code and determines which component(s) to return to the application based on application domain rules [7]. Keywords: Software Reuse, Atomic Domains, Java Atomic Domains, Reusable Java Domains. 3 1 Introduction Various approaches to the ease and effectiveness of component reuse [1,2,3] have been researched. This work attempts to further explore the application of the Atomic Domains framework [4,5,6,7] in developing reusable domainspecific components. The concept of atomic domains promotes component reuse. The general model of the Atomic Domains framework focuses on the developer’s perspective of application development with reuse. The model facilitates effective domain-specific component reuse as applied by its wrapper. In this work, the components are source code, and the domain is Java applications using the Java library components. The application of the framework requires an effort to construct each atomic domain and its wrapper. The programming effort can vary. In this work, the effort is specific to the Java library components and is illustrated by sample Javabased atomic domains that are kept simple for proof of concept purpose. This work is a contribution to component-based software development that has become a defacto requirement for many in today’s software industry. 2 Java Atomic Domains The goal of this work is to apply the Atomic Domains framework model to the Java library classes and packages to facilitate effective reuse of library components in the development of Java applications, ease component management, and minimize coding effort. To achieve this goal, our approach is to develop illustrative atomic domains of related Java library components, and develop applications to demonstrate component reuse through the wrappers of developed atomic domains. Analysis of the Java library showed that the library includes a large number of related components (classes and packages). Sample applications selected for this work include the following: Linear-Data Structure (DS) Atomic Domain: The DS atomic domain and its wrapper manager, called DSWrapper, are implemented as a class that includes data structure classes such as linked-list, stack, and vector. The purpose of wrapping reusable components into an atomic domain has been applied to data structure classes to minimize the design overhead and coding effort. To demonstrate the concept of wrapping existing components and retaining their original functionalities, the DSWrapper class defines a set of methods such as: add, clear, get, getSize, remove, and set as its API. This atomic domain is kept simple for illustration purposes. Atomic Domain Framework The Atomic Domain framework defines each atomic domain based on one related context. All reusable (and irreducible) components related to the context are conceptually placed in the same atomic domain [5]. Each atomic domain is associated with a wrapper, which includes a wrapper manager component. Application domain rules are built into the wrapper manager and are part of its construction process. The rules determine how the user application selects components from Non-Linear Data Structure (NDS) Atomic Domain: The NDS atomic domain and its wrapper manager, called NDSWrapper, are implemented as a class that includes non-linear data structures such as Tree, Binary Tree, UGraph (un-weighted graph), and Abstract Graph. Like the DS atomic domain, wrapping reusable components into an atomic domain helps reduce coding effort and speeds up application development. The included components retain their original functionalities. The NDSWrapper class defines methods for Tree, Graph, and Binary Tree structures. The Tree methods include createNode, deleteNode, setRoot, setLeave, create1stBranch, createBranch, and createTree; the Graph methods include createUgraph, addEdge, and getShortestPath; and the Binary Tree methods include search, insert, delete and getRoot. It should be noted that the linear and non-linear data structure components are separated into 2 atomic domains for illustration purposes. If such concepts are fully implemented in Java, many of the cumbersome design and coding of applications can be eliminated. From a programmer’s perspective, this means less coding effort and fewer visible components to be accounted for. GUI Atomic Domain: The GUI atomic domain and its wrapper, called GUIWrapper, include a number of GUI components such as button, checkboxes, dropdown lists, menu, and others. A GUI component, such as a button, can be associated with several classes. To build a button, the developer has to use a class to specify the color of the button, another class to apply a border to the button, and another class to specify the font style of the label or a class to specify an image picture for the button, and so on. This lengthy process can be repeated to build all the components that make up the application interface. With atomic domains, wrapping related components into an atomic domain can speed up the coding process significantly. With the GUI components (classes) being wrapped into one atomic domain, the application developer can use one reference to interact with the atomic domain (GUIWrapper) to build needed GUI components. GUI components share common methods. For example, most GUI components define methods to change background and foreground colors, methods to modify label names, and others. The GUIWrapper (implemented as a class) incorporates most of these methods. This makes learning how to reuse GUI components easier by giving the user an abstract view of the GUIWrapper class with its methods that can provide the same functionalities of all the methods of many different GUI components. To motivate the wrapping of existing components and retaining their original functionalities, the GUIWrapper class defines methods such as: setBackgroundColor, setForgroundColor, setFont, setLabelName, setVisibility, isVisible, setEnabled, isEnable, setNewSize, getText, addActionListener, and addFocusListener. These methods provide the same functionalities as the individual methods. Input/Output (IO) Atomic Domain: The IO atomic domain and its wrapper, called IOWrapper and is implemented as a class, includes a number of I/O classes such as File, ObjectInputStream, ObjectOutputStream, FileInputStream, FileOutputStream, BufferedReader, BufferedWriter, FileReader, FileWriter, DataInputStream, and DataOutputStream. Because of the nature of Java and in order to build an application with IO capabilities, the programmer has to use several library classes, such as the File class, to associate a file name and location with a File object during runtime. Also, InputStream and OutputStream classes are used to allow the application to read and write to a secondary storage device, and several more classes are used to handle the buffering process. With the IOWrapper and instead of having to decide how many classes and which one to use for IO process, the application developer can use one reference to the IOWrapper class and the wrapper manager creates necessary I/O components for the application. The listed IO components share common methods. For example, these IO components provide a link between the running program and a file object on an IO device. These IO components also have similar methods used to transfer data (read/write) to and from a file located on the IO device. IO classes do not have as many methods as the GUI classes because they provide a different type of service. To demonstrate the wrapping of existing components and retaining their original functionalities, the IOWrapper class defines methods such as readLine, read, writeFile, newLine, readFile, closeReaderStream, and closeWriterStream. 4 Illustrative Applications Selected applications are described in this section to illustrate how Java atomic domains and their wrappers facilitate effective reuse of components in the development of Java applications. The approach is to contrast programming effort (lines of code) with and without using atomic domains. The selected applications are Nine Tail, Tree, Payroll, and Bank Account. These applications use the Java atomic domains described above. Nine Tail Application: The Nine Tail application uses BreadthFirst Search (BFS) algorithm to solve the Nail Tail problem. Nine coins are placed in a three by three matrix with some facing up and others facing down. A legal move is to take any coin that is facing up and reverse it, together with the coins adjacent to it. The task is to find the minimum number of moves that lead to all coins facing down. The problem is solved when all coins are facing down. This application utilizes the NDSWrapper class. Figures 1 and 2 show the source code before and after using the NDSWrapper class in the solution. The coding effort in Figure-2 is simpler than that in Figure-1. Tree Application: The Tree application creates a folder structure and allows user to add, delete, and update values under a specified node. This application utilizes the NDSWrapper class. Figures 3 and 4 show the source code before and after using the NDS atomic domain. In Figure-3 the user needs to explicitly identify all the non-linear data structure components and their types while in Figure-4 the user creates all the NDS objects from the same wrapper class. Bank Account Application: The Bank Account example illustrates the process of creating account objects and allowing the user to save account information into a file. This application utilizes the GUIWrapper, IOWrapper, and DSWrapper classes. Figures 5 and 6 show partial code before and after using the GUI, IO, and DS atomic domains. The omitted code in both Figures is identical. In Figure-5, the user needs to explicitly identify all required GUI, IO, and DS components and their types; while in Figure-6 the user creates all GUI, IO, and DS objects from respective same wrapper class. The coding effort in Figure-6 is simpler than that in Figure-5. // Application Nine Tail without using the // NDSWrapper classes import java.util.*; public class NineTailModel { private ArrayList<Node> nodes = new ArrayList<Node>(); // Vertices private ArrayList<AbstractGraph.Edge> edges = new ArrayList<AbstractGraph.Edge>(); // Store edges private UnweightedGraph graph; // Define a graph private AbstractGraph.Tree tree; // Define a tree public NineTailModel() { createNodes(); // Create nodes createEdges(); // Create edges graph = new UnweightedGraph(edges, nodes); tree = graph.bfs(511); } private void createNodes() { for (int k1 = 0; k1 <= 1; k1++) { for (int k2 = 0; k2 <= 1; k2++) { for (int k3 = 0; k3 <= 1; k3++) { for (int k4 = 0; k4 <= 1; k4++) { for (int k5 = 0; k5 <= 1; k5++) { for (int k6 = 0; k6 <= 1; k6++) { for (int k7 = 0; k7 <= 1; k7++) { for (int k8 = 0; k8 <= 1; k8++) { for (int k9 = 0; k9 <= 1; k9++) { nodes.add(new Node(k1, k2, k3, k4,k5, k6, k7, k8, k9)); } } } } } } } } } } public static class Node { int[][] matrix = new int[3][3]; Node(int ...numbers) { // Variable-length argument int k = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { matrix[i][j] = numbers[k++]; } } } Node(int[][] numbers) { this.matrix = numbers; } public boolean equals(Object o) { int[][] anotherMatrix = ((Node)o).matrix; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (matrix[i][j] != anotherMatrix[i][j]) { return false; } } } return true; // Nodes with the same matrix values } public String toString() { StringBuilder result = new StringBuilder(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { result.append(matrix[i][j] + " "); } result.append("\n"); } return result.toString(); } } private void createEdges() { for (Node node : nodes) { int u = nodes.indexOf(node); // node index int[][] matrix = node.matrix; // matrix for the node for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (matrix[i][j] == 0) { Node adjacentNode = getAdjacentNode(matrix, i, j); int v = nodes.indexOf(adjacentNode); edges.add(new AbstractGraph.Edge(v, u)); } } } } } private Node getAdjacentNode(int[][] matrix, int i, int j) { int[][] matrixOfNextNode = new int[3][3]; for (int i1 = 0; i1 < 3; i1++) { for (int j1 = 0; j1 < 3; j1++) { matrixOfNextNode[i1][j1] = matrix[i1][j1]; } } flipACell(matrixOfNextNode, i - 1, j);// Top flipACell(matrixOfNextNode, i + 1,j); // Bottom flipACell(matrixOfNextNode, i, j - 1);// Left flipACell(matrixOfNextNode, i, j + 1);// Right flipACell(matrixOfNextNode, i, j); // Self return new Node(matrixOfNextNode); } private void flipACell(int[][] matrix, int i, int j) { if (i >= 0 && i <= 2 && j >= 0 && j <= 2) { // Within boundary if (matrix[i][j] == 0) { matrix[i][j] = 1; // Flip from 0 to 1 } else { matrix[i][j] = 0; // Flip from 1 to 0 } } } public LinkedList<Node> getShortestPath(Node node) { Iterator iterator = tree.pathIterator(nodes.indexOf(node)); LinkedList list = new LinkedList(); while (iterator.hasNext()) list.addFirst(iterator.next()); return list; } } Figure-1: Application Nine Tail without using the NDSWrapper Class. Payroll Application: The Payroll application calculates the check amount by allowing the user to enter the hours worked and the pay rate. The application allows the user to save the check amount to a text file. This application uses the GUIWrapper and IOWrapper classes to create the user interface and to add saving to file capability. Without atomic domains, the user needs to explicitly identify all required GUI components and their types; while with atomic domains the user creates all GUI objects from the same wrapper classes. Coding with the later approach is simpler than with the former approach. // Application Nine Tail with using the // NDSWrapper classes import java.util.*; public class NineTailModel { private NDSWrapper ugraph = new NDSWrapper("ugraph");; private ArrayList<NDSWrapper.Node> nodes = new ArrayList<NDSWrapper.Node>(); // Vertices public NineTailModel() { ugraph = new NDSWrapper("ugraph"); createNodes(); // Create nodes createEdges(); // Create edges ugraph.createUgraph(nodes); } private void createNodes() { for (int k1 = 0; k1 <= 1; k1++) { for (int k2 = 0; k2 <= 1; k2++) { for (int k3 = 0; k3 <= 1; k3++) { for (int k4 = 0; k4 <= 1; k4++) { for (int k5 = 0; k5 <= 1; k5++) { for (int k6 = 0; k6 <= 1; k6++) { for (int k7 = 0; k7 <= 1; k7++) { for (int k8 = 0; k8 <= 1; k8++) { for (int k9 = 0; k9 <= 1; k9++) { nodes.add(new NDSWrapper.Node(k1, k2, k3, k4,k5, k6, k7, k8, k9)); } } } } } } } } } } private void createEdges() { for (NDSWrapper.Node node : nodes) { int u = nodes.indexOf(node); // node index int[][] matrix = node.matrix; // matrix for the node for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (matrix[i][j] == 0) { NDSWrapper.Node adjacentNode = getAdjacentNode(matrix, i, j); int v = nodes.indexOf(adjacentNode); ugraph.addEdge(v, u); } } } } } private NDSWrapper.Node getAdjacentNode(int[][] matrix, int i, int j) { int[][] matrixOfNextNode = new int[3][3]; for (int i1 = 0; i1 < 3; i1++) { for (int j1 = 0; j1 < 3; j1++) { matrixOfNextNode[i1][j1] = matrix[i1][j1]; } } flipACell(matrixOfNextNode, i - 1, j); // Top neighbor flipACell(matrixOfNextNode, i + 1, j); // Bottom neighbor flipACell(matrixOfNextNode, i, j - 1); // Left neighbor flipACell(matrixOfNextNode, i, j + 1); // Right neighbor flipACell(matrixOfNextNode, i, j); // Flip self return new NDSWrapper.Node(matrixOfNextNode); } private void flipACell(int[][] matrix, int i, int j) { if (i >= 0 && i <= 2 && j >= 0 && j <= 2) { // Within boundary if (matrix[i][j] == 0) { matrix[i][j] = 1; // Flip from 0 to 1 } else { matrix[i][j] = 0; // Flip from 1 to 0 } } } public LinkedList<NDSWrapper.Node> getShortestPath(NDSWrapper.Node node){ LinkedList list = new LinkedList(); list = ugraph.getShortestPath(nodes,node); return list; } } Figure-2: Application Nine Tail using the NDSWrapper Class. 5 Conclusion The implementation of component reuse ranges from isolated solution such as using new languages [8], wrapping legacy components [9], refactoring [10], program mining [11], product line technologies [12,13], and product populations [14] to the use of current industry standards for distributed components. This work supports the local component model, where a component is defined as Java source code of a module, class, function, or code snippet. The presented applications focus on Java classes as components. The components’ atomic domains group similar and related Java components that are bound with a wrapper, and the domain is utilized via a single atomic reference in the application source code. These applications illustrate ease of reuse as well as encourage a higher amount of reuse of Java library components. The initial outcomes from this work indicate promising results. The example applications illustrate the possibility of achieving effective reuse of Java components and that the programming effort for the application developer can be made easier. Instead of requiring detailed knowledge of every library component and package and their methods, with this approach the application developer needs to know about smaller number of components (atomic domains) and their methods. From lines of code perspective, some atomic domains can reduce source code significantly, such as in the case of the Payroll and Bank Account applications. In other cases, such as the GUI atomic domain, the user creates many objects (components) from a single atomic domain without the need to know the internal details for each created object. During the development we found that using atomic domains and their wrappers is easier to get the applications developed than not using these wrapper classes. In addition to having to deal with few wrapper classes, the management overhead of such classes was improved compared to dealing with the many classes in the library. Future work will focus on identifying more related components in the Java library, developing more concrete atomic domains and their wrappers; developing more illustrative applications, and studying improvement in coding effort (with vs. without wrapper classes). import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.GraphicsEnvironment; import java.awt.Image; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JRootPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; public class TreeWrap extends JFrame { private JTree tree; private String nodename, parentname, rootname; private DefaultTreeModel model; private DefaultMutableTreeNode nNode; private DefaultMutableTreeNode dNode; private DefaultMutableTreeNode parent, outdoor, indoor,ski, soccer, tennis, pingpong, iceskate, chess; private String [] sport = {"Outdoor Sport","Ski","Soccer","Tennis", "Indoor Sport","Pingpong","Ice skate","Chess"}; ReadImage img, oimg, cimg; Image i1, i2, i3; ImageIcon licon, oicon, cicon; DefaultTreeCellRenderer renderer, renderer2; public TreeWrap(int indexicon){ parent = new DefaultMutableTreeNode("Sport", true); outdoor = new DefaultMutableTreeNode("Outdoor Sport"); indoor = new DefaultMutableTreeNode("Indoor Sport"); ski = new DefaultMutableTreeNode("Ski"); soccer = new DefaultMutableTreeNode("Soccer"); tennis = new DefaultMutableTreeNode("Tennis"); pingpong = new DefaultMutableTreeNode("Pingpong"); iceskate = new DefaultMutableTreeNode("Ice Skate"); chess = new DefaultMutableTreeNode("Chess"); parent.add(outdoor); parent.add(indoor); outdoor.add(ski); outdoor.add(soccer); outdoor.add(tennis); indoor.add(pingpong); indoor.add(iceskate); indoor.add(chess); tree = new JTree(parent); setCustomIcon(); setNoIcon(); setStandardIcon(); if (indexicon == 1){ tree.setCellRenderer(renderer); // custom icon }else if(indexicon ==2){ tree.setCellRenderer(renderer2); // no icon } tree.setBackground(Color.PINK); setTitle("Sample tree"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Dimension d = new Dimension(600, 600); setSize(d.width, d.height); setLayout(new BorderLayout()); add(tree, BorderLayout.CENTER); setUndecorated(true); getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG ); setVisible(true); } public void setFont(int index, int size){ GraphicsEnvironment gEnv = GraphicsEnvironment.getLocalGraphicsEnvironment(); String envfonts[] = gEnv.getAvailableFontFamilyNames(); tree.setFont(new Font(envfonts[index], Font.BOLD,size)); } public void AddNode(String nodename, String parentname){ model = (DefaultTreeModel)tree.getModel(); nNode = new DefaultMutableTreeNode(nodename); if (parentname == "Sport"){ model.insertNodeInto(nNode, parent, parent.getChildCount()); }else if (parentname == "Outdoor Sport"){ model.insertNodeInto(nNode, outdoor, outdoor.getChildCount()); }else if (parentname == "Indoor Sport"){ model.insertNodeInto(nNode, indoor, indoor.getChildCount()); }else if (parentname == "Ski"){ model.insertNodeInto(nNode, ski, ski.getChildCount()); }else if (parentname == "Soccer"){ model.insertNodeInto(nNode, soccer, soccer.getChildCount()); }else if (parentname == "Tennis"){ model.insertNodeInto(nNode, tennis, tennis.getChildCount()); }else if (parentname == "Pingpong"){ model.insertNodeInto(nNode, pingpong, pingpong.getChildCount()); }else if (parentname == "Ice Skate"){ model.insertNodeInto(nNode, iceskate, iceskate.getChildCount()); }else if (parentname == "Chess"){ model.insertNodeInto(nNode, chess, chess.getChildCount()); } } public void deleteNode(String nodename){ model = (DefaultTreeModel) (tree.getModel()); if (nodename == "Sport"){ model.removeNodeFromParent(parent); }else if (nodename == "Outdoor Sport"){ model.removeNodeFromParent(outdoor); }else if (nodename == "Indoor Sport"){ model.removeNodeFromParent(indoor); }else if (nodename == "Ski"){ model.removeNodeFromParent(ski); }else if (nodename == "Soccer"){ model.removeNodeFromParent(soccer); }else if (nodename == "Tennis"){ model.removeNodeFromParent(tennis); }else if (nodename == "Pingpong"){ model.removeNodeFromParent(pingpong); }else if (nodename == "Ice Skate"){ model.removeNodeFromParent(iceskate); }else if (nodename == "Chess"){ model.removeNodeFromParent(chess); } } public String[] getSport() { return sport; } public void setStandardIcon(){} public void setNoIcon(){ renderer2 = new DefaultTreeCellRenderer(); renderer2.setOpenIcon(null); renderer2.setClosedIcon(null); renderer2.setLeafIcon(null); } public void setCustomIcon(){ img = new ReadImage(0); oimg = new ReadImage(1); cimg = new ReadImage(2); i1 = img.getImage(); i2 = oimg.getImage(); i3 = cimg.getImage(); licon = new ImageIcon(i1); oicon = new ImageIcon(i2); cicon = new ImageIcon(i3); renderer = new DefaultTreeCellRenderer(); renderer.setOpenIcon(oicon); renderer.setClosedIcon(cicon); renderer.setLeafIcon(licon); } } Figure-3: Application Tree without using NDSWrapper class. // Application Tree with using the // NDSWrapper classes import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JRootPane; import trees.NDSWrapper; public class TreeWrap extends JFrame { private NDSWrapper wtree; private String [] sport = {"Outdoor Sport","Ski","Soccer","Tennis", "Indoor Sport","Pingpong","Ice skate","Chess"}; private String nodename,parentname; public TreeWrap(int indexicon){ nodename = "Special"; parentname ="Sport"; wtree = new NDSWrapper("tree","Sport",sport); wtree.create1stBranch(0); wtree.create1stBranch(4); wtree.createBranch(0,1); wtree.createBranch(0,2); wtree.createBranch(0,3); wtree.createBranch(4,5); wtree.createBranch(4,6); wtree.createBranch(4,7); wtree.createTree(indexicon); wtree.setColor(); setTitle("Sample tree"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Dimension d = new Dimension(600, 600); setSize(d.width, d.height); setLayout(new BorderLayout()); add(wtree, BorderLayout.CENTER); setUndecorated(true); getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DI ALOG); setVisible(true); } public void AddNode(String nodename, String parentname){ this.nodename = nodename; this.parentname = parentname; wtree.createNode(nodename,parentname); } public void DeleteNode(int nodeindex){ wtree.deleteNode(nodeindex); } public void SetFontNode(int fontfamilyIndex, int fontsize){ wtree.setFont(fontfamilyIndex, fontsize); } public String[] getSport() { return sport; } } Figure-4: Application Tree using the NDSWrapper Class. // Application BankAccounts without using the // GUI, IO, and DS Wrapper classes import java.io.Serializable; import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class BankAccounts extends JFrame implements ActionListener{ // This section declares the GUI & Data Structure // components needed for this program. JTextField jAccountNumber, jBalance; JLabel accountNumber, balance; JButton bSave; JTextArea display; JScrollPane sp_display; LinkedList accountList; Account tempAccount = new Account(); public BankAccounts() { BankAccountsLayout customLayout = new BankAccountsLayout(); getContentPane().setFont(new Font("Helvetica", Font.PLAIN, 12)); getContentPane().setLayout(customLayout); // This section create the GUI & Data // Structure objects. jAccountNumber accountNumber jBalance balance bSave display accountList // the rest of //identical in = new JTextField(); = new JLabel(); = new JTextField(); = new JLabel(); = new JButton(); = new JTextArea(); = new LinkedList(); the code is omitted. It is both versions. // This section enables write/read // capabilities without using wrappers. public void writeAndRead() { try { File file = new File("bankAccounts.dat"); if(!file.exists()){ boolean c = file.createNewFile(); } FileOutputStream fileOutputStream = new FileOutputStream(file); ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream); objectOutputStream.writeObject(accountList); objectOutputStream.flush(); objectOutputStream.close(); ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(file)); AccountList = (LinkedList) objectInputStream.readObject(); objectInputStream.close(); } catch(ClassNotFoundException cnfexception) { System.err.println ("ClassNotFoundException "); } catch(IOException ioexception) { System.err.println("IOException ");} } // the rest of the code is omitted as it is // identical in both versions of the application. Figure-5: Application Bank Account without using the GUIWrapper, IOWrapper, and DSWrapper classes. // Application BankAccounts using the GUI, IO, and // DS Wrapper classes import import import import // This section create the GUI & DS objects. jAccountNumber = new GuiWrapper("textfield"); accountNumber = new GuiWrapper("label"); jBalance = new GuiWrapper("textfield"); java.io.Serializable; java.awt.*; java.awt.event.*; javax.swing.*; balance = new bSave = new display = new accountList = public class BankAccountsWithWrappers extends JFrame implements ActionListener{ // This section declares the GUI & Data // Structure components needed for this // program. GuiWrapper jAccountNumber, jBalance, accountNumber, balance, bSave, display; JScrollPane sp_display; DSWrapper accountList; Account tempAccount = new Account(); public BankAccountsWithWrappers() { BankAccountsLayout customLayout = new BankAccountsLayout(); getContentPane().setFont(new Font("Helvetica", Font.PLAIN, 12)); getContentPane().setLayout (customLayout); GuiWrapper("label"); GuiWrapper("button"); GuiWrapper("textarea"); new DSWrapper("linkedlist"); // This section utilizes the IOWrapper class // for write/read purposes. public void writeAndRead() { IOWrapper ioWrapper = new IOWrapper("objectio", “bankAccounts.dat"); ioWrapper.write(accountList); ioWrapper.closeWriterStream(); accountList.linkedList = LinkedList)ioWrapper.readObject(); ioWrapper.closeReaderStream(); } // the rest of the code is omitted as it is // identical in both versions of the application. Figure-6: Application Bank Account using the GUIWrapper, IOWrapper, and DSWrapper classes. 6 REFERENCES [1] T. Khammaci, M. Oussalah, and B. Giuseppin. Towards a reuse-based pattern representation and search model. Proceedings of the International Conference of Software Engineering Research and Engineering (SERP’02), Jun 24-27, 2002, SCREA Press, pp. 267-273. B. Councill and G.T. Heineman, G.T. Component based software engineering and issue of trust. Proceedings of the International Conference on Software Engineering (ICSE’00), Limerick, Ireland, 661-664. F. Bachman, L. Bass, et. al. Technical Concepts of Component-Based Software Engineering. Technical Report, CMU/SEI-2000-TR-008, ESC-TR-2000-007. Mauricio Ordoñez and Hisham M. Haddad. Enhanced Component Reuse with Atomic Domains: Application Scenarios. Proceedings of the IEEE International Conference on Information Technology: New Generations (ITNG’07), Las Vegas, April 2007, pp. 597-602. Hisham Haddad and Ying Xie. Wrapper-Based Framework for Domain-Specific Software Reuse. Journal of Information Science and Engineering (JISE), Vol. 22, No. 2, March 2006, pp. 269-282. Hisham Haddad and Walter Fortner. A Framework for Domain-Specific Reusable Components. Proceedings of the International Conference on Software Engineering Research and Practice (SERP'03), Las Vegas, Nevada, June 2003, pp. 384-390. [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] Hisham Haddad and Herbert Tesser. Reusable Subsystems: Domain-Based Approach. Proceedings of the Annual ACM Symposium on Applied Computing, Madrid, Spain, March 2002. Vugranam C. Sreedhar. Mixin’Up Components. ICSE’02, Orlando, Florida, May 2002, pp. 198-207. Jiang Guo and Yuehong Liao. Integrating Software Components through Wrapper Technologies. Proceedings of the 7’th IASTED International Conference, Software Engineering and Applications, Marina Del Rey, CA, November 2003, pp. 441446. Rodrigo E. Caballero and Steven A. Demurjian Sr., Towards the Formalization of a Reusability Framework for Refactoring, ICSR-7, LNCS-2319, 2002, pp. 293-308. Donglin Xia, Yaoxue Zhang and Ling Zhou, A Multi-Agent System for Program Mining, Proceedings of the 7’th IASTED International Conference, Software Engineering and Applications, Marina Del Rey, CA, November 2003, pp. 95-99. Kwanwoo Lee, Kyo C. Kang and Jaejoon Lee, Concepts and Guidelines of Feature Modeling for Product Line Software Engineering, ICSR-7, LNCS-2319, 2002, pp. 62-77. Colin Atkinson and Dirk Muthig, Enhancing Component Reusability through Product Line Technology, ICSR-7, LNCS2319, 2002, pp. 93-108. Rob van Ommering, Building Product Populations with Software Components, ICSE’02, Orlando, Florida, May 2002, pp. 255-265.