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 */
031 package ca.uhn.hl7v2.view;
032
033 import java.awt.BorderLayout;
034 import java.awt.event.WindowAdapter;
035 import java.awt.event.WindowEvent;
036 import java.io.File;
037 import java.io.FileReader;
038
039 import javax.swing.JFrame;
040 import javax.swing.JScrollPane;
041 import javax.swing.JTree;
042 import javax.swing.tree.DefaultMutableTreeNode;
043 import javax.swing.tree.MutableTreeNode;
044
045 import org.slf4j.Logger;
046 import org.slf4j.LoggerFactory;
047
048 import ca.uhn.hl7v2.HL7Exception;
049 import ca.uhn.hl7v2.model.Composite;
050 import ca.uhn.hl7v2.model.Group;
051 import ca.uhn.hl7v2.model.Message;
052 import ca.uhn.hl7v2.model.Primitive;
053 import ca.uhn.hl7v2.model.Segment;
054 import ca.uhn.hl7v2.model.Structure;
055 import ca.uhn.hl7v2.model.Type;
056 import ca.uhn.hl7v2.model.Varies;
057 import ca.uhn.hl7v2.parser.EncodingCharacters;
058 import 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")
067 public 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 }