001/** 002 * The contents of this file are subject to the Mozilla Public License Version 1.1 003 * (the "License"); you may not use this file except in compliance with the License. 004 * You may obtain a copy of the License at http://www.mozilla.org/MPL/ 005 * Software distributed under the License is distributed on an "AS IS" basis, 006 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the 007 * specific language governing rights and limitations under the License. 008 * 009 * The Original Code is "TreePanel.java". Description: 010 * "This is a Swing panel that displays the contents of a Message object in a JTree" 011 * 012 * The Initial Developer of the Original Code is University Health Network. Copyright (C) 013 * 2001. All Rights Reserved. 014 * 015 * Contributor(s): ______________________________________. 016 * 017 * Alternatively, the contents of this file may be used under the terms of the 018 * GNU General Public License (the "GPL"), in which case the provisions of the GPL are 019 * applicable instead of those above. If you wish to allow use of your version of this 020 * file only under the terms of the GPL and not to allow others to use your version 021 * of this file under the MPL, indicate your decision by deleting the provisions above 022 * and replace them with the notice and other provisions required by the GPL License. 023 * If you do not delete the provisions above, a recipient may use your version of 024 * this file under either the MPL or the GPL. 025 * 026 */ 027 028/* 029 * Created on October 17, 2001, 11:44 AM 030 */ 031package ca.uhn.hl7v2.view; 032 033import java.awt.BorderLayout; 034import java.awt.event.WindowAdapter; 035import java.awt.event.WindowEvent; 036import java.io.File; 037import java.io.FileReader; 038 039import javax.swing.JFrame; 040import javax.swing.JScrollPane; 041import javax.swing.JTree; 042import javax.swing.tree.DefaultMutableTreeNode; 043import javax.swing.tree.MutableTreeNode; 044 045import org.slf4j.Logger; 046import org.slf4j.LoggerFactory; 047 048import ca.uhn.hl7v2.HL7Exception; 049import ca.uhn.hl7v2.model.Composite; 050import ca.uhn.hl7v2.model.Group; 051import ca.uhn.hl7v2.model.Message; 052import ca.uhn.hl7v2.model.Primitive; 053import ca.uhn.hl7v2.model.Segment; 054import ca.uhn.hl7v2.model.Structure; 055import ca.uhn.hl7v2.model.Type; 056import ca.uhn.hl7v2.model.Varies; 057import ca.uhn.hl7v2.parser.EncodingCharacters; 058import ca.uhn.hl7v2.parser.PipeParser; 059 060/** 061 * This is a Swing panel that displays the contents of a Message object in a JTree. 062 * The tree currently only expands to the field level (components shown as one node). 063 * @author Bryan Tripp (bryan_tripp@sourceforge.net) 064 * @deprecated 065 */ 066@SuppressWarnings("serial") 067public class TreePanel extends javax.swing.JPanel { 068 069 private static final Logger log = LoggerFactory.getLogger(TreePanel.class); 070 071 private EncodingCharacters encChars; 072 private Message message; 073 074 /** Creates new TreePanel */ 075 public TreePanel() { 076 this.encChars = new EncodingCharacters('|', null); 077 } 078 079 /** 080 * Updates the panel with a new Message. 081 */ 082 public void setMessage(Message message) { 083 this.message = message; 084 if (message == null) { 085 this.removeAll(); 086 this.revalidate(); 087 return; 088 } 089 090 DefaultMutableTreeNode top = new DefaultMutableTreeNode(message.getClass().getName()); 091 addChildren(message, top); 092 093 JTree tree = new JTree(top); 094 //JScrollPane treeView = new JScrollPane(tree); 095 this.removeAll(); 096 this.add(tree); 097 this.revalidate(); 098 } 099 100 /** 101 * Returns the message that is currently displayed in the tree panel. 102 */ 103 public Message getMessage() { 104 return this.message; 105 } 106 107 /** 108 * Adds the children of the given group under the given tree node. 109 */ 110 private void addChildren(Group messParent, MutableTreeNode treeParent) { 111 String[] childNames = messParent.getNames(); 112 int currChild = 0; 113 for (int i = 0; i < childNames.length; i++) { 114 try { 115 Structure[] childReps = messParent.getAll(childNames[i]); 116 for (int j = 0; j < childReps.length; j++) { 117 DefaultMutableTreeNode newNode = null; 118 if (childReps[j] instanceof Group) { 119 String groupName = childReps[j].getClass().getName(); 120 groupName = groupName.substring(groupName.lastIndexOf('.') + 1, groupName.length()); 121 newNode = new DefaultMutableTreeNode(groupName + " (rep " + j + ")"); 122 addChildren((Group)childReps[j], newNode); 123 } else if (childReps[j] instanceof Segment) { 124 newNode = new DefaultMutableTreeNode(PipeParser.encode((Segment)childReps[j], encChars)); 125 addChildren((Segment)childReps[j], newNode); 126 } 127 treeParent.insert(newNode, currChild++); 128 } 129 } catch (HL7Exception e) { 130 e.printStackTrace(); 131 } 132 } 133 } 134 135 /** 136 * Add fields of a segment to the tree ... 137 */ 138 private void addChildren(Segment messParent, MutableTreeNode treeParent) { 139 int n = messParent.numFields(); 140 int currChild = 0; 141 for (int i = 1; i <= n; i++) { 142 try { 143 Type[] reps = messParent.getField(i); 144 for (int j = 0; j < reps.length; j++) { 145 String field = PipeParser.encode(reps[j], encChars); 146 DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("Field " + i + " rep " + j + " (" + getLabel(reps[j]) + "): " + field); 147 addChildren(reps[j], newNode); 148 treeParent.insert(newNode, currChild++); 149 } 150 } catch (HL7Exception e) { 151 e.printStackTrace(); 152 } 153 } 154 } 155 156 /** 157 * Adds children to the tree. If the Type is a Varies, the Varies data are 158 * added under a new node called "Varies". If there are extra components, 159 * these are added under a new node called "ExtraComponents" 160 */ 161 private void addChildren(Type messParent, MutableTreeNode treeParent) { 162 if (Varies.class.isAssignableFrom(messParent.getClass())) { 163 //DefaultMutableTreeNode variesNode = new DefaultMutableTreeNode("Varies"); 164 //treeParent.insert(variesNode, treeParent.getChildCount()); 165 Type data = ((Varies) messParent).getData(); 166 DefaultMutableTreeNode dataNode = new DefaultMutableTreeNode(getLabel(data)); 167 treeParent.insert(dataNode, 0); 168 addChildren(data, dataNode); 169 } else { 170 if (Composite.class.isAssignableFrom(messParent.getClass())) { 171 addChildren((Composite)messParent, treeParent); 172 } else if (Primitive.class.isAssignableFrom(messParent.getClass())) { 173 addChildren((Primitive)messParent, treeParent); 174 } 175 176 if (messParent.getExtraComponents().numComponents() > 0) { 177 DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("ExtraComponents"); 178 treeParent.insert(newNode, treeParent.getChildCount()); 179 for (int i = 0; i < messParent.getExtraComponents().numComponents(); i++) { 180 DefaultMutableTreeNode variesNode = new DefaultMutableTreeNode("Varies"); 181 newNode.insert(variesNode, i); 182 addChildren(messParent.getExtraComponents().getComponent(i), variesNode); 183 } 184 } 185 } 186 } 187 188 /** 189 * Adds components of a composite to the tree ... 190 */ 191 private void addChildren(Composite messParent, MutableTreeNode treeParent) { 192 Type[] components = messParent.getComponents(); 193 for (int i = 0; i < components.length; i++) { 194 DefaultMutableTreeNode newNode; 195 newNode = new DefaultMutableTreeNode(getLabel(components[i])); 196 addChildren(components[i], newNode); 197 treeParent.insert(newNode, i); 198 } 199 } 200 201 /** 202 * Adds single text value to tree as a leaf 203 */ 204 private void addChildren(Primitive messParent, MutableTreeNode treeParent) { 205 DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(messParent.getValue()); 206 treeParent.insert(newNode, 0); 207 } 208 209 /** 210 * Returns the unqualified class name as a label for tree nodes. 211 */ 212 private static String getLabel(Object o) { 213 String name = o.getClass().getName(); 214 return name.substring(name.lastIndexOf('.')+1, name.length()); 215 } 216 217 /** 218 * A convenience method for displaying a message by creating a new 219 * TreePanel and displaying the given message in a new window. 220 * Currently only works with v2.4 messages. 221 */ 222 public static void showInNewWindow(Message message) { 223 //Create the top-level container and add contents to it. 224 JFrame frame = new JFrame(message.getClass().getName()); 225 226 try { 227 TreePanel panel = new TreePanel(); 228 panel.setMessage(message); 229 JScrollPane scroll = new JScrollPane(panel); 230 frame.getContentPane().add(scroll, BorderLayout.CENTER); 231 232 //Finish setting up the frame 233 frame.addWindowListener(new WindowAdapter() { 234 public void windowClosing(WindowEvent e) { 235 System.exit(0); 236 } 237 }); 238 239 frame.pack(); 240 frame.setVisible(true); 241 } catch (Exception e) { 242 System.err.println("Can't display message in new window: "); 243 e.printStackTrace(); 244 } 245 } 246 247 /** 248 * Opens window and displays a message in a file (file named in command line arg). 249 */ 250 public static void main(String args[]) { 251 if (args.length != 1) { 252 System.out.println("Usage: TreePanel msg_file_name"); 253 System.exit(1); 254 } 255 256 try { 257 PipeParser parser = new PipeParser(); 258 File messageFile = new File(args[0]); 259 long fileLength = messageFile.length(); 260 FileReader r = new FileReader(messageFile); 261 char[] cbuf = new char[(int)fileLength]; 262 System.out.println("Reading message file ... " + r.read(cbuf) + " of " + fileLength + " chars"); 263 r.close(); 264 String messString = String.valueOf(cbuf); 265 Message mess = parser.parse(messString); 266 System.out.println("Got message of type " + mess.getClass().getName()); 267 showInNewWindow(mess); 268 269 //write message to console ... 270 System.out.println(parser.encode(mess, "VB")); 271 } catch (Exception e) { 272 e.printStackTrace(); 273 log.error( e.getMessage(), e ); 274 } 275 } 276 277}