1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 package com.sun.star.xml.security.uno;
29 
30 import javax.xml.parsers.DocumentBuilder;
31 import javax.xml.parsers.DocumentBuilderFactory;
32 import javax.xml.parsers.ParserConfigurationException;
33 
34 import java.io.File;
35 import java.io.IOException;
36 import java.io.FileOutputStream;
37 import java.io.FileInputStream;
38 import java.io.InputStream;
39 import java.io.ByteArrayInputStream;
40 import java.io.UnsupportedEncodingException;
41 
42 import org.w3c.dom.Document;
43 import org.w3c.dom.Node;
44 import org.w3c.dom.NodeList;
45 
46 /* Basic GUI components */
47 import javax.swing.JFrame;
48 import javax.swing.JPanel;
49 import javax.swing.JScrollPane;
50 import javax.swing.JTree;
51 import javax.swing.JButton;
52 import javax.swing.JCheckBox;
53 import javax.swing.JTextArea;
54 import javax.swing.JTextField;
55 import javax.swing.JFileChooser;
56 import javax.swing.ToolTipManager;
57 import javax.swing.JTable;
58 import javax.swing.JLabel;
59 import javax.swing.BorderFactory;
60 
61 /* GUI components for right-hand side */
62 import javax.swing.JSplitPane;
63 import javax.swing.JOptionPane;
64 import javax.swing.JTabbedPane;
65 
66 
67 /* GUI support classes */
68 import java.awt.BorderLayout;
69 import java.awt.Dimension;
70 import java.awt.Container;
71 import java.awt.Toolkit;
72 import java.awt.event.WindowEvent;
73 import java.awt.event.WindowAdapter;
74 import java.awt.event.ActionEvent;
75 import java.awt.event.ActionListener;
76 
77 /* For creating borders */
78 import javax.swing.border.EmptyBorder;
79 import javax.swing.border.BevelBorder;
80 import javax.swing.border.CompoundBorder;
81 
82 /* For creating a TreeModel */
83 import javax.swing.tree.TreePath;
84 import java.util.Vector;
85 
86 /* UNO classes */
87 import com.sun.star.uno.UnoRuntime;
88 import com.sun.star.bridge.XUnoUrlResolver;
89 import com.sun.star.lang.XMultiComponentFactory;
90 import com.sun.star.beans.XPropertySet;
91 import com.sun.star.uno.XComponentContext;
92 import com.sun.star.xml.sax.XDocumentHandler;
93 
94 import com.sun.star.xml.crypto.*;
95 import com.sun.star.xml.crypto.sax.*;
96 
97 public class TestTool extends JFrame implements ActionListener
98 {
99 	/*
100 	 * xml security framewrok component names
101 	 */
102 	public static String SIGNATURECREATOR_COMPONENT = "com.sun.star.xml.crypto.sax.SignatureCreator";
103 	public static String SIGNATUREVERIFIER_COMPONENT = "com.sun.star.xml.crypto.sax.SignatureVerifier";
104 	public static String ENCRYPTOR_COMPONENT = "com.sun.star.xml.crypto.sax.Encryptor";
105 	public static String DECRYPTOR_COMPONENT = "com.sun.star.xml.crypto.sax.Decryptor";
106 	public static String SAXEVENTKEEPER_COMPONENT = "com.sun.star.xml.crypto.sax.SAXEventKeeper";
107 
108 	/*
109 	 * Java-based component names
110 	 */
111 	public static String SEINITIALIZER_COMPONENT_JAVA = "com.sun.star.xml.security.bridge.jxsec.SEInitializer_JxsecImpl";
112 	public static String XMLSIGNATURE_COMPONENT_JAVA = "com.sun.star.xml.security.bridge.jxsec.XMLSignature_JxsecImpl";
113 	public static String XMLENCRYPTION_COMPONENT_JAVA = "com.sun.star.xml.security.bridge.jxsec.XMLEncryption_JxsecImpl";
114 	public static String XMLDOCUMENTWRAPPER_COMPONENT_JAVA = "com.sun.star.xml.security.bridge.jxsec.XMLDocumentWrapper_JxsecImpl";
115 
116 	/*
117 	 * C-based component names
118 	 */
119 	public static String SEINITIALIZER_COMPONENT_C = "com.sun.star.xml.crypto.SEInitializer";
120 	public static String XMLSIGNATURE_COMPONENT_C = "com.sun.star.xml.crypto.XMLSignature";
121 	public static String XMLENCRYPTION_COMPONENT_C = "com.sun.star.xml.crypto.XMLEncryption";
122 	public static String XMLDOCUMENTWRAPPER_COMPONENT_C = "com.sun.star.xml.wrapper.XMLDocumentWrapper";
123 
124 	/* url resolver name */
125 	public static String UNOURLRESOLVER = "com.sun.star.bridge.UnoUrlResolver";
126 
127 	/*
128 	 * connection URL
129 	 */
130 	private String m_unoURL = "uno:socket,host=localhost,port=2002;urp;StarOffice.ServiceManager";
131 
132 	/* key file */
133 	private String m_javaTokenFile = null;
134 	private String m_nssTokenPath = null;
135 
136 	/* User Interfaces */
137 	private JButton m_goButton;
138 	private JButton m_stepButton;
139 	private JButton m_startButton;
140 	private JButton m_openButton;
141 	private JCheckBox m_isExportingButton;
142 	private JCheckBox m_isJavaComponentButton;
143 	private JButton m_saveButton;
144 	private JButton m_batchButton;
145 	private JTree m_leftTree;
146 	private JTextArea m_leftTextArea;
147 	private JTree m_middleTree;
148 	private JTree m_rightTree;
149 	private JTabbedPane m_leftTabPane;
150 	private JTextArea m_bufferNodeTextArea;
151 	private JLabel m_saxChainLabel;
152 	private JTextField m_saxEventText;
153 	private JTable m_unsolvedReferenceTable;
154 
155 	/*
156 	 * whether a batch file is running,
157 	 * if so, no message box is popped up
158 	 */
159 	private boolean m_bIsBatchRunning = false;
160 
161 	/*
162 	 * whether the UI needs to be updated.
163 	 * when user click the "go" button, the UI needs
164 	 * not to be updated step by step for performance
165 	 * reason
166 	 */
167 	private boolean m_bIsUIUpdateSuppressed = false;
168 
169 	/*
170 	 * three DOM tree adapter
171 	 */
172 	private DomToTreeModelAdapter m_leftTreeModelAdapter;
173 	private DomToTreeModelAdapter m_middleTreeModelAdapter;
174 	private DomToTreeModelAdapter m_rightTreeModelAdapter;
175 
176 	/*
177 	 * the current directory, which reserves the default
178 	 * location when user open/save a file.
179 	 */
180 	private File m_currentDirectory = null;
181 
182 	/*
183 	 * the log file
184 	 */
185 	private FileOutputStream m_logFileOutputStream = null;
186 
187 	/*
188 	 * the thread which is parsing the current XML
189 	 * file
190 	 */
191 	private ParsingThread m_parsingThread;
192 
193 	/*
194 	 * whether is exporting or importing
195 	 */
196 	private boolean m_bIsExporting;
197 
198 	/*
199 	 * whether java based component or c based component
200 	 * is used now
201 	 */
202 	private boolean m_bIsJavaBased;
203 
204 	/*
205 	 * XML security component interface
206 	 */
207 	private XComponentContext m_xRemoteContext = null;
208 	private XMultiComponentFactory m_xRemoteServiceManager = null;
209 	private XXMLSecurityContext m_xXMLSecurityContext = null;
210 	private XXMLSignature m_xXMLSignature = null;
211 	private XXMLEncryption m_xXMLEncryption = null;
212 	private XSEInitializer m_xSEInitializer = null;
213 
214 	/*
215 	 * SAX event collector for the middle tree and the right tree
216 	 */
217 	private SAXEventCollector m_rightTreeEventCollector = null;
218 	private SAXEventCollector m_middleTreeEventCollector = null;
219 
220 	/*
221 	 * security framework controller
222 	 */
223 	private XMLSecurityFrameworkController m_xmlSecurityFrameworkController = null;
224 
225 	/* org.w3c.dom.Document */
226 	private Document m_document;
227 
228 	/* represents whether "Go" or "Step" */
229 	private boolean stepMode = true;
230 
231 /**************************************************************************************
232  * private methods
233  **************************************************************************************/
234 
235 
236 	/******************************************************************************
237 	 * UI related methods
238 	 ******************************************************************************/
239 
240 	/*
241 	 * initalizes the UI.
242 	 */
243 	private void initUI()
244 	{
245 		m_leftTreeModelAdapter = new DomToTreeModelAdapter(m_document);
246 		m_middleTreeModelAdapter = new DomToTreeModelAdapter(m_document);
247 		m_rightTreeModelAdapter = new DomToTreeModelAdapter(m_document);
248 
249 		m_parsingThread = null;
250 
251 		m_leftTree.setModel(m_leftTreeModelAdapter);
252 		m_middleTree.setModel(m_middleTreeModelAdapter);
253 		m_rightTree.setModel(m_rightTreeModelAdapter);
254 	}
255 
256 	/*
257 	 * constructs the user interface.
258 	 */
259 	private Container buildUI(int width, int height)
260 	{
261 		JPanel mainPanel = new JPanel();
262 
263 		int frameHeight = height-40;
264 		int leftWindowWidth = (width-40)/3;
265 		int middleWindowWidth = leftWindowWidth;
266 		int rightWindowWidth = leftWindowWidth;
267 		int leftPaneWidth = leftWindowWidth+middleWindowWidth;
268 		int frameWidth = leftPaneWidth + rightWindowWidth;
269 
270 		/* Make a nice border */
271 		EmptyBorder emptyBorder = new EmptyBorder(5,5,5,5);
272 		BevelBorder bevelBorder = new BevelBorder(BevelBorder.LOWERED);
273 		CompoundBorder compoundBorder = new CompoundBorder(emptyBorder,bevelBorder);
274 		mainPanel.setBorder(new CompoundBorder(compoundBorder,emptyBorder));
275 
276 		/* Set up the tree */
277 		m_leftTreeModelAdapter = new DomToTreeModelAdapter(m_document);
278 		m_middleTreeModelAdapter = new DomToTreeModelAdapter(m_document);
279 		m_rightTreeModelAdapter = new DomToTreeModelAdapter(m_document);
280 
281 		m_leftTree = new JTree(m_leftTreeModelAdapter);
282 		m_leftTextArea = new JTextArea();
283 		m_middleTree = new JTree(m_middleTreeModelAdapter);
284 		m_rightTree = new JTree(m_rightTreeModelAdapter);
285 
286 		ToolTipManager.sharedInstance().registerComponent(m_leftTree);
287 		ToolTipManager.sharedInstance().registerComponent(m_middleTree);
288 		ToolTipManager.sharedInstance().registerComponent(m_rightTree);
289 
290 		/* Builds left tab pane */
291 		JScrollPane leftTreePane = new JScrollPane(m_leftTree);
292 		JScrollPane leftTextPane = new JScrollPane(m_leftTextArea);
293 		m_leftTabPane= new JTabbedPane();
294 		m_leftTabPane.add("Tree View",leftTreePane);
295 		m_leftTabPane.add("Text View",leftTextPane);
296 
297 		/* Builds middle tree pane */
298 		JScrollPane middleTreePane = new JScrollPane(m_middleTree);
299 
300 		/* Builds right tree pane */
301 		JScrollPane rightTreePane = new JScrollPane(m_rightTree);
302 		rightTreePane.setBorder(BorderFactory.createCompoundBorder(
303                         BorderFactory.createTitledBorder("Result"),
304                         BorderFactory.createEmptyBorder(8,8,8,8)));
305 
306 		m_leftTabPane.setPreferredSize(
307 			new Dimension( leftWindowWidth, frameHeight ));
308 		middleTreePane.setPreferredSize(
309 			new Dimension( middleWindowWidth, frameHeight ));
310 		rightTreePane.setPreferredSize(
311 			new Dimension( rightWindowWidth, frameHeight ));
312 
313 		/* Builds the SAX event text box */
314 		m_saxEventText = new JTextField();
315 
316 		/* Builds the unsolved reference table */
317 		m_unsolvedReferenceTable = new JTable(
318 				new UnsolvedReferenceTableModel(this));
319 
320 		/* Builds the BufferNode information text area */
321 		m_bufferNodeTextArea = new JTextArea();
322 
323 		/* Builds the SAX chain information label */
324 		m_saxChainLabel = new JLabel();
325 
326 		/* Builds the left pane */
327 		JPanel tabPaneWithSaxEventPane = new JPanel();
328 		tabPaneWithSaxEventPane.setLayout(new BorderLayout());
329 		tabPaneWithSaxEventPane.add("Center",m_leftTabPane);
330 		tabPaneWithSaxEventPane.add("South",new JScrollPane(m_saxEventText));
331 
332 		JSplitPane leftPane =
333 			new JSplitPane( JSplitPane.VERTICAL_SPLIT,
334 				tabPaneWithSaxEventPane,
335 				new JScrollPane(m_unsolvedReferenceTable));
336 		leftPane.setBorder(BorderFactory.createCompoundBorder(
337                         BorderFactory.createTitledBorder("Original"),
338                         BorderFactory.createEmptyBorder(8,8,8,8)));
339 
340 		leftPane.setContinuousLayout( true );
341 		leftPane.setDividerLocation( frameHeight*2/3 );
342 		leftPane.setPreferredSize(
343 			new Dimension( leftWindowWidth, frameHeight ));
344 
345 		/* Builds the middle pane */
346 		JPanel bufferNodeWithSaxChainPane = new JPanel();
347 		bufferNodeWithSaxChainPane.setLayout(new BorderLayout());
348 		bufferNodeWithSaxChainPane.add("Center",m_bufferNodeTextArea);
349 		bufferNodeWithSaxChainPane.add("South",new JScrollPane(m_saxChainLabel));
350 
351 		JSplitPane middlePane =
352 			new JSplitPane( JSplitPane.VERTICAL_SPLIT,
353 				middleTreePane,
354 				new JScrollPane(bufferNodeWithSaxChainPane));
355 
356 		middlePane.setBorder(BorderFactory.createCompoundBorder(
357                         BorderFactory.createTitledBorder("Insight SAXEventKeeper"),
358                         BorderFactory.createEmptyBorder(8,8,8,8)));
359 
360 		middlePane.setContinuousLayout( true );
361 		middlePane.setDividerLocation( frameHeight/2+5 );
362 		middlePane.setPreferredSize(
363 			new Dimension( middleWindowWidth, frameHeight ));
364 
365 		/* Builds the whole frame pane */
366 		JSplitPane leftWithMiddlePane =
367 			new JSplitPane( JSplitPane.HORIZONTAL_SPLIT,
368 				leftPane,
369 				middlePane );
370 		leftWithMiddlePane.setContinuousLayout( true );
371 		leftWithMiddlePane.setDividerLocation( leftWindowWidth );
372 		leftWithMiddlePane.setPreferredSize(
373 			new Dimension( leftPaneWidth + 10, frameHeight+10 ));
374 
375 		JSplitPane framePane =
376 			new JSplitPane( JSplitPane.HORIZONTAL_SPLIT,
377 				leftWithMiddlePane,
378 				rightTreePane );
379 
380 
381 		framePane.setContinuousLayout( true );
382 		framePane.setDividerLocation(leftPaneWidth+10 );
383 		framePane.setPreferredSize(
384 			new Dimension( frameWidth + 20, frameHeight+10 ));
385 
386 		/* Adds all GUI components to the main panel */
387 		mainPanel.setLayout(new BorderLayout());
388 		mainPanel.add("Center", framePane );
389 
390 		m_openButton = new JButton("Open...");
391 		m_openButton.addActionListener(this);
392 
393 		m_goButton = new JButton("Go!");
394 		m_goButton.addActionListener(this);
395 
396 		m_stepButton = new JButton("Step");
397 		m_stepButton.addActionListener(this);
398 
399 		m_startButton = new JButton("Start");
400 		m_startButton.addActionListener(this);
401 		m_startButton.setEnabled(false);
402 
403 		m_isExportingButton = new JCheckBox("export, not import", true);
404 		m_isJavaComponentButton = new JCheckBox("use java component", false);
405 
406 		m_saveButton = new JButton("Save...");
407 		m_saveButton.addActionListener(this);
408 
409 		m_batchButton = new JButton("Batch...");
410 		m_batchButton.addActionListener(this);
411 
412 		JPanel buttonPanel = new JPanel();
413 		buttonPanel.add(m_batchButton);
414 		buttonPanel.add(m_openButton);
415 		buttonPanel.add(m_startButton);
416 		buttonPanel.add(m_goButton);
417 		buttonPanel.add(m_stepButton);
418 		buttonPanel.add(m_isExportingButton);
419 		buttonPanel.add(m_isJavaComponentButton);
420 		buttonPanel.add(m_saveButton);
421 
422 		mainPanel.add("South", buttonPanel);
423 
424 		enableGoButton(false);
425 
426 		return mainPanel;
427 	}
428 
429 	/*
430 	 * enables/disables the Go(and Step) button.
431 	 */
432 	private void enableGoButton(boolean enabled)
433 	{
434 		m_goButton.setEnabled(enabled);
435 		m_stepButton.setEnabled(enabled);
436 	}
437 
438 	/*
439 	 * updates the unsolved reference information.
440 	 */
441 	private void updatesUnsolvedReferencesInformation()
442 	{
443 		m_unsolvedReferenceTable.setModel(new UnsolvedReferenceTableModel(this));
444 	}
445 
446 	/*
447 	 * adjusts the view of the tree in order to make the
448 	 * particular Node into the focus tree leaf.
449 	 */
450 	private void updatesTree(Node node, JTree tree)
451 	{
452 		int i=0;
453 		int currentLine = 0;
454 
455 		while (i<tree.getRowCount())
456 		{
457 			TreePath treePath = tree.getPathForRow(i);
458 			tree.expandPath(treePath);
459 
460 			AdapterNode adapterNode = (AdapterNode)treePath.getLastPathComponent();
461 
462 			if (node == adapterNode.getNode())
463 			{
464 				tree.addSelectionPath(treePath);
465 				currentLine = i;
466 			}
467 
468 			++i;
469 		}
470 
471 		tree.setCellRenderer(new XMLTreeCellRanderer(node));
472 		tree.scrollRowToVisible(currentLine);
473 	}
474 
475 	/******************************************************************************
476 	 * action listener related methods.
477 	 ******************************************************************************/
478 
479 	/*
480 	 * reads in a document, either the document is a file or
481 	 * is a text paragraph.
482 	 */
483 	private void openDocument()
484 	{
485 		if (m_leftTabPane.getSelectedIndex() == 0)
486 		{
487 			File f = openFile();
488 			if (f != null)
489 			{
490 				parseFile(f);
491 			}
492 		}
493 		else
494 		{
495 			String text = m_leftTextArea.getText();
496 
497 			try
498 			{
499 				parseStream(new ByteArrayInputStream(text.getBytes("UTF-8")));
500 			}
501 			catch(UnsupportedEncodingException e)
502 			{
503 				e.printStackTrace();
504 			}
505 
506 			m_leftTabPane.setSelectedIndex(0);
507 		}
508 	}
509 
510 	/*
511 	 * save the result tree to a file.
512 	 */
513 	private void saveResult()
514 	{
515 		saveFile();
516 	}
517 
518 	/*
519 	 * selects a batch file to excute.
520 	 */
521 	private void openBatch()
522 	{
523 		File f = openFile();
524 		if (f != null)
525 		{
526 			runBatch(f);
527 		}
528 	}
529 
530 	/*
531 	 * makes the current operation to an end.
532 	 */
533 	private void endMission()
534 	{
535 		enableGoButton(false);
536 		m_parsingThread = null;
537 
538 		if (m_xmlSecurityFrameworkController != null)
539 		{
540 			m_xmlSecurityFrameworkController.endMission();
541 		}
542 
543 		updatesUIs();
544 
545 		m_xmlSecurityFrameworkController = null;
546 		freeComponents();
547 
548 		System.gc();
549 	}
550 
551 
552 	/******************************************************************************
553 	 * UNO component related methods
554 	 ******************************************************************************/
555 
556 	/*
557 	 * connects the SO server.
558 	 */
559 	private void connectSO(String unoUrlString)
560 	{
561 		if (unoUrlString != null)
562 		{
563 			m_unoURL = new String(unoUrlString);
564 		}
565 
566 		try
567 		{
568 			m_xRemoteServiceManager = getRemoteServiceManager(m_unoURL);
569 		}
570 		catch(Exception e)
571 		{
572 			e.printStackTrace();
573 		}
574 	}
575 
576 	/*
577 	 * creates UNO components.
578 	 */
579 	private boolean createComponents()
580 	{
581 		try
582 		{
583 			String SEInitializer_comp;
584 			String XMLSignature_comp;
585 			String XMLEncryption_comp;
586 			String tokenPath;
587 
588 			if (m_bIsJavaBased)
589 			{
590 				SEInitializer_comp = SEINITIALIZER_COMPONENT_JAVA;
591 				XMLSignature_comp = XMLSIGNATURE_COMPONENT_JAVA;
592 				XMLEncryption_comp = XMLENCRYPTION_COMPONENT_JAVA;
593 				tokenPath = m_javaTokenFile;
594 			}
595 			else
596 			{
597 				SEInitializer_comp = SEINITIALIZER_COMPONENT_C;
598 				XMLSignature_comp = XMLSIGNATURE_COMPONENT_C;
599 				XMLEncryption_comp = XMLENCRYPTION_COMPONENT_C;
600 				tokenPath = m_nssTokenPath;
601 			}
602 
603 			Object seInitializerObj = m_xRemoteServiceManager.createInstanceWithContext(
604 				SEInitializer_comp, m_xRemoteContext);
605 
606 			if (seInitializerObj == null)
607 			{
608 				freeComponents();
609 				return false;
610 			}
611 
612 			m_xSEInitializer = (XSEInitializer)UnoRuntime.queryInterface(
613 						XSEInitializer.class, seInitializerObj);
614 
615 			m_xXMLSecurityContext = m_xSEInitializer.createSecurityContext(tokenPath);
616 
617 			Object xmlSignatureObj = m_xRemoteServiceManager.createInstanceWithContext(
618 				XMLSignature_comp, m_xRemoteContext);
619 
620 			if (xmlSignatureObj == null)
621 			{
622 				freeComponents();
623 				return false;
624 			}
625 
626 			m_xXMLSignature = (XXMLSignature)UnoRuntime.queryInterface(
627 						XXMLSignature.class, xmlSignatureObj);
628 
629 			Object xmlEncryptionObj = m_xRemoteServiceManager.createInstanceWithContext(
630 				XMLEncryption_comp, m_xRemoteContext);
631 
632 			if (xmlEncryptionObj == null)
633 			{
634 				freeComponents();
635 				return false;
636 			}
637 
638 			m_xXMLEncryption = (XXMLEncryption)UnoRuntime.queryInterface(
639 						XXMLEncryption.class, xmlEncryptionObj);
640 
641 			return true;
642 		}
643 		catch(Exception e)
644 		{
645 			freeComponents();
646 			e.printStackTrace();
647 			return false;
648 		}
649 	}
650 
651         /*
652          * frees UNO components.
653          */
654 	private void freeComponents()
655 	{
656 		try
657 		{
658 			if (m_xXMLSecurityContext != null)
659 			{
660 				m_xSEInitializer.freeSecurityContext(m_xXMLSecurityContext);
661 				m_xXMLSecurityContext = null;
662 			}
663 
664 			m_xXMLSignature = null;
665 			m_xXMLEncryption = null;
666 			m_xSEInitializer = null;
667 		}
668 		catch(Exception e)
669 		{
670 			e.printStackTrace();
671 		}
672 	}
673 
674 	/*
675 	 * getRemoteServiceManager
676 	 */
677 	private XMultiComponentFactory getRemoteServiceManager(String unoUrl) throws java.lang.Exception
678 	{
679 		if (m_xRemoteContext == null)
680 		{
681 			/*
682 			 * First step: create local component context, get local servicemanager and
683 			 * ask it to create a UnoUrlResolver object with an XUnoUrlResolver interface
684 			 */
685 			XComponentContext xLocalContext =
686 				com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(null);
687 			XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();
688 			Object urlResolver = xLocalServiceManager.createInstanceWithContext(
689 				UNOURLRESOLVER, xLocalContext );
690 			/*
691 			 * query XUnoUrlResolver interface from urlResolver object
692 			 */
693 			XUnoUrlResolver xUnoUrlResolver = (XUnoUrlResolver) UnoRuntime.queryInterface(
694 				XUnoUrlResolver.class, urlResolver );
695 
696 			/*
697 			 * Second step: use xUrlResolver interface to import the remote StarOffice.ServiceManager,
698 			 * retrieve its property DefaultContext and get the remote servicemanager
699 			 */
700 			Object initialObject = xUnoUrlResolver.resolve( unoUrl );
701 			XPropertySet xPropertySet = (XPropertySet)UnoRuntime.queryInterface(
702 			XPropertySet.class, initialObject);
703 			Object context = xPropertySet.getPropertyValue("DefaultContext");
704 			m_xRemoteContext = (XComponentContext)UnoRuntime.queryInterface(
705 				XComponentContext.class, context);
706 		}
707 		return m_xRemoteContext.getServiceManager();
708 	}
709 
710 
711 	/******************************************************************************
712 	 * XML related methods
713 	 ******************************************************************************/
714 
715 	/*
716 	 * removes all empty text node inside the particular element
717 	 */
718 	private void removeEmptyText(Node node)
719 	{
720 		int type = node.getNodeType();
721 		NodeList children;
722 		int i;
723 
724 		switch (type)
725 		{
726 		case Node.DOCUMENT_NODE:
727 		case Node.ELEMENT_NODE:
728 			Node child = node.getFirstChild();
729 			while (child!= null)
730 			{
731 				Node nextSibling = child.getNextSibling();
732 				int childType = child.getNodeType();
733 
734 				if (childType==Node.TEXT_NODE)
735 				{
736 					String message = child.getNodeValue().trim();
737 					if (message == null || message.length()<=0)
738 					{
739 						node.removeChild(child);
740 					}
741 				}
742 				else if (childType == Node.ELEMENT_NODE)
743 				{
744 					removeEmptyText(child);
745 				}
746 
747 				child = nextSibling;
748 			}
749 			break;
750 		}
751 	}
752 
753 	/*
754 	 * reads a stream, and parses it into the original tree.
755 	 */
756 	private void parseStream(InputStream is)
757 	{
758 		try
759 		{
760 			DocumentBuilderFactory factory =
761 				DocumentBuilderFactory.newInstance();
762 			m_document = null;
763 			m_startButton.setEnabled(false);
764 			initUI();
765 
766 			/* factory.setValidating(true); */
767 			/* factory.setNamespaceAware(true); */
768 
769 			try
770 			{
771 				DocumentBuilder builder = factory.newDocumentBuilder();
772 				m_document = builder.parse(is);
773 				m_startButton.setEnabled(true);
774 				initUI();
775 			}
776 			catch (ParserConfigurationException pce)
777 			{
778 				pce.printStackTrace();
779 			}
780 			catch (IOException ioe)
781 			{
782 				ioe.printStackTrace();
783 			}
784 		}
785 		catch(Exception exce)
786 		{
787 			System.out.println("input stream Exception");
788 		}
789 	}
790 
791 
792 	/******************************************************************************
793 	 * file operation related methods
794 	 ******************************************************************************/
795 
796 	/*
797 	 * opens a file, and parses it into the original tree.
798 	 */
799 	private void parseFile(File name)
800 	{
801 		try
802 		{
803 			FileInputStream fis = new FileInputStream(name);
804 			parseStream(fis);
805 			fis.close();
806 		}
807 		catch(Exception exce)
808 		{
809 			System.out.println("open file Exception");
810 		}
811 	}
812 
813 
814 	/*
815 	 * selects a file to open
816 	 */
817 	private File openFile()
818 	{
819 		File rc = null;
820 
821 		JFileChooser fileChooser= new JFileChooser();
822 
823 		fileChooser.setDialogTitle("Select File To Open");
824 		fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
825 
826 		fileChooser.setApproveButtonText("Ok");
827 
828 		if (m_currentDirectory == null)
829 		{
830 			fileChooser.rescanCurrentDirectory();
831 		}
832 		else
833 		{
834 			fileChooser.setCurrentDirectory(m_currentDirectory);
835 		}
836 
837 		fileChooser.setFileFilter(new XMLFileFilter());
838 
839 		int result = fileChooser.showDialog(this,null);
840 		if (result==fileChooser.APPROVE_OPTION)
841 		{
842 			m_currentDirectory = fileChooser.getCurrentDirectory();
843 			rc = fileChooser.getSelectedFile();
844 		}
845 
846 		return rc;
847 	}
848 
849 	private void saveFile()
850 	{
851 		JFileChooser fileChooser= new JFileChooser();
852 
853 		fileChooser.setDialogTitle("Select File To Save");
854 		fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
855 
856 		fileChooser.setApproveButtonText("Ok");
857 
858 		if (m_currentDirectory == null)
859 		{
860 			fileChooser.rescanCurrentDirectory();
861 		}
862 		else
863 		{
864 			fileChooser.setCurrentDirectory(m_currentDirectory);
865 		}
866 
867 		fileChooser.setFileFilter(new XMLFileFilter());
868 
869 		int result = fileChooser.showDialog(this,null);
870 		if (result==fileChooser.APPROVE_OPTION)
871 		{
872 			try
873 			{
874 				m_currentDirectory = fileChooser.getCurrentDirectory();
875 				saveFile(fileChooser.getSelectedFile());
876 			}
877 			catch(Exception exce)
878 			{
879 				System.out.println("save file Exception");
880 				exce.printStackTrace();
881 			}
882 		}
883 	}
884 
885 	/*
886 	 * excutes a batch file.
887 	 */
888 	private void runBatch(File f)
889 	{
890 		FileInputStream fis = null;
891 
892 		try
893 		{
894 			fis = new FileInputStream(f);
895 			StringBuffer commandBuffer = new StringBuffer();
896 
897 			m_logFileOutputStream = new FileOutputStream("TestTool-log.txt");
898 			m_bIsBatchRunning = true;
899 			int ch = 0;
900 
901 			while (ch != -1)
902 			{
903 				ch = fis.read();
904 
905 				if (ch != 0x0a && ch != -1)
906 				{
907 					if (ch != 0x0d)
908 					{
909 						commandBuffer.append((char)ch);
910 					}
911 				}
912 				else
913 				{
914 					String command = new String(commandBuffer);
915 					if (command.startsWith("Open "))
916 					{
917 						m_logFileOutputStream.write(("start \""+command+"\" ...\n").getBytes());
918 						String fileName = command.substring(5);
919 						parseFile(new File(fileName));
920 						m_logFileOutputStream.write("command end \n\n".getBytes());
921 					}
922 					else if (command.startsWith("Use Java Component"))
923 					{
924 						m_logFileOutputStream.write(("start \""+command+"\" ...\n").getBytes());
925 						m_isJavaComponentButton.setSelected(true);
926 						m_logFileOutputStream.write("command end \n\n".getBytes());
927 					}
928 					else if (command.startsWith("Use C++ Component"))
929 					{
930 						m_logFileOutputStream.write(("start \""+command+"\" ...\n").getBytes());
931 						m_isJavaComponentButton.setSelected(false);
932 						m_logFileOutputStream.write("command end \n\n".getBytes());
933 					}
934 					else if (command.startsWith("Go "))
935 					{
936 						m_logFileOutputStream.write(("start \""+command+"\" ...\n").getBytes());
937 						String opera = command.substring(3);
938 						if (opera.equals("Sign") || opera.equals("Encrypt"))
939 						{
940 							m_isExportingButton.setSelected(true);
941 						}
942 						else
943 						{
944 							m_isExportingButton.setSelected(false);
945 						}
946 
947 						startsUp();
948 						if (m_parsingThread != null)
949 						{
950 							m_bIsUIUpdateSuppressed = true;
951 							try{
952 								while (m_parsingThread.nextStep());
953 								endMission();
954 							}
955 							catch(Exception e)
956 							{
957 								System.out.println("exception happen during batch:"+e);
958 								e.printStackTrace();
959 							}
960 
961 							m_bIsUIUpdateSuppressed = false;
962 							updatesUIs();
963 						}
964 						m_logFileOutputStream.write("command end \n\n".getBytes());
965 					}
966 					else if (command.startsWith("Save "))
967 					{
968 						m_logFileOutputStream.write(("start \""+command+"\" ...\n").getBytes());
969 						String fileName = command.substring(5);
970 						saveFile(new File(fileName));
971 						m_logFileOutputStream.write("command end \n\n".getBytes());
972 					}
973 
974 					commandBuffer = new StringBuffer();
975 				}
976 			}
977 
978 			m_bIsBatchRunning = false;
979 			m_logFileOutputStream.close();
980 			m_logFileOutputStream = null;
981 
982 			fis.close();
983 			fis = null;
984 		}
985 		catch(java.io.IOException e)
986 		{
987 			e.printStackTrace();
988 		}
989 	}
990 
991 	/*
992 	 * save the current result tree to a particular file.
993 	 */
994 	private void saveFile(File f)
995 	{
996 		try{
997 			FileOutputStream fos = new FileOutputStream(f);
998 			SAXEventPrinter.display((Document)m_rightTreeEventCollector.getDocument(),
999 				0,fos,false);
1000 			fos.close();
1001 		}catch(Exception e)
1002 		{
1003 			e.printStackTrace();
1004 		}
1005 	}
1006 
1007 	/******************************************************************************
1008 	 * others
1009 	 ******************************************************************************/
1010 
1011 	/*
1012 	 * starts up the operation.
1013 	 */
1014 	private void startsUp()
1015 	{
1016 		if (m_parsingThread != null)
1017 		{
1018 			m_parsingThread = null;
1019 		}
1020 
1021 		m_bIsExporting = m_isExportingButton.isSelected();
1022 		m_bIsJavaBased = m_isJavaComponentButton.isSelected();
1023 
1024 		if (createComponents())
1025 		{
1026 			m_rightTreeEventCollector = new SAXEventCollector(this);
1027 
1028 			m_parsingThread = new ParsingThread(
1029 				m_document,
1030 				null,
1031 				this);
1032 
1033 			m_xmlSecurityFrameworkController =
1034 				new XMLSecurityFrameworkController(
1035 					this,
1036 					m_bIsExporting,
1037 					m_bIsJavaBased,
1038 					m_rightTreeEventCollector,
1039 					m_parsingThread,
1040 					m_xXMLSecurityContext,
1041 					m_xXMLSignature,
1042 					m_xXMLEncryption,
1043 					m_xRemoteServiceManager,
1044 					m_xRemoteContext);
1045 
1046 			enableGoButton(true);
1047 		}
1048 		else
1049 		{
1050 			showMessage("Error in creating XML Security Components!");
1051 		}
1052 	}
1053 
1054 /**************************************************************************************
1055  * protected methods
1056  **************************************************************************************/
1057 
1058 	/******************************************************************************
1059 	 * UI related methods
1060 	 ******************************************************************************/
1061 
1062 	/*
1063 	 * updates the sax chain information.
1064 	 */
1065 	protected void updatesSAXChainInformation(String chainStr)
1066 	{
1067 		m_saxChainLabel.setText(chainStr);
1068 	}
1069 
1070 	/*
1071 	 * update the current SAX event information.
1072 	 */
1073 	protected void updatesCurrentSAXEventInformation(String event)
1074 	{
1075 		m_saxEventText.setText(event);
1076 	}
1077 
1078 	/*
1079 	 * updates all information in the UI.
1080 	 */
1081 	protected void updatesUIs()
1082 	{
1083 		if (!m_bIsUIUpdateSuppressed)
1084 		{
1085 			m_leftTree.clearSelection();
1086 			updatesTree(null, m_leftTree);
1087 
1088 			if (m_xmlSecurityFrameworkController != null)
1089 			{
1090 				String bufferNodeTreeText = m_xmlSecurityFrameworkController.getBufferNodeTreeInformation();
1091 				if (bufferNodeTreeText == null)
1092 				{
1093 					m_middleTree.setVisible(false);
1094 					m_bufferNodeTextArea.setText("No XML Security Related");
1095 				}
1096 				else
1097 				{
1098 					m_middleTreeEventCollector = new SAXEventCollector(null);
1099 					m_xmlSecurityFrameworkController.getDocument(m_middleTreeEventCollector);
1100 
1101 					m_middleTreeModelAdapter = new DomToTreeModelAdapter(m_middleTreeEventCollector.getDocument());
1102 					m_middleTree.setModel(m_middleTreeModelAdapter);
1103 					updatesTree(null, m_middleTree);
1104 					m_middleTree.setVisible(true);
1105 					m_bufferNodeTextArea.setText(bufferNodeTreeText);
1106 				}
1107 			}
1108 			else
1109 			{
1110 				m_middleTree.setVisible(false);
1111 				m_bufferNodeTextArea.setText("No XMLImporter/XMLExporter");
1112 			}
1113 
1114 			if (m_rightTreeEventCollector != null)
1115 			{
1116 				m_rightTreeModelAdapter = new DomToTreeModelAdapter((Document)m_rightTreeEventCollector.getDocument());
1117 				m_rightTree.setModel(m_rightTreeModelAdapter);
1118 				updatesTree((Node)m_rightTreeEventCollector.getCurrentElement(), m_rightTree);
1119 			}
1120 
1121 			updatesUnsolvedReferencesInformation();
1122 		}
1123 	}
1124 
1125 	/*
1126 	 * shows a message.
1127 	 */
1128 	protected void showMessage(String msg)
1129 	{
1130 		if (m_bIsBatchRunning)
1131 		{
1132 			try
1133 			{
1134 				if (!msg.startsWith("Message from : SAXEventKeeper"))
1135 				{
1136 					byte [] b = msg.getBytes();
1137 					m_logFileOutputStream.write("        ".getBytes());
1138 
1139 					for (int i=0; i<b.length; ++i)
1140 					{
1141 						m_logFileOutputStream.write(b[i]);
1142 						if (b[i] == '\n')
1143 						{
1144 							m_logFileOutputStream.write("        ".getBytes());
1145 						}
1146 					}
1147 					m_logFileOutputStream.write("\n        ==============================\n".getBytes());
1148 				}
1149 			}
1150 			catch(IOException e)
1151 			{
1152 				e.printStackTrace();
1153 			}
1154 		}
1155 		else
1156 		{
1157 			if (stepMode)
1158 			{
1159 				JOptionPane optionPane = new JOptionPane();
1160 				optionPane.showMessageDialog(this, msg, "TestTool Notification", JOptionPane.INFORMATION_MESSAGE);
1161 			}
1162 			else
1163 			{
1164 				Object[] options = { "OK", "Go back to step mode" };
1165 				if (1 == JOptionPane.showOptionDialog(this, msg, "TestTool Notification",
1166 					JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE,
1167 					null, options, options[0]))
1168 				{
1169 					stepMode = true;
1170 				}
1171 			}
1172 		}
1173 	}
1174 
1175 
1176 	/******************************************************************************
1177 	 * information retrieving
1178 	 ******************************************************************************/
1179 
1180 	/*
1181 	 * gets all unsolved reference ids.
1182 	 * a reference id is the value of the id attribute of an
1183 	 * referenced element.
1184 	 */
1185 	protected Vector getUnsolvedReferenceIds()
1186 	{
1187 		Vector rc;
1188 
1189 		if (m_xmlSecurityFrameworkController == null)
1190 		{
1191 			rc = new Vector();
1192 		}
1193 		else
1194 		{
1195 			rc = ((XMLSecurityFrameworkController)m_xmlSecurityFrameworkController).
1196 				getUnsolvedReferenceIds();
1197 		}
1198 
1199 		return rc;
1200 	}
1201 
1202 	/*
1203 	 * gets all unsolved reference keeper ids.
1204 	 * a reference keeper id is the id which the SAXEventKeeper uses
1205 	 * to identify the corresponding BufferNode.
1206 	 */
1207 	protected Vector getUnsolvedReferenceKeeperIds()
1208 	{
1209 		Vector rc;
1210 
1211 		if (m_xmlSecurityFrameworkController == null)
1212 		{
1213 			rc = new Vector();
1214 		}
1215 		else
1216 		{
1217 			rc = ((XMLSecurityFrameworkController)m_xmlSecurityFrameworkController).
1218 				getUnsolvedReferenceKeeperIds();
1219 		}
1220 
1221 		return rc;
1222 	}
1223 
1224 	/*
1225 	 * gets all unsolved references' remaining numbers.
1226 	 * a remaining number is that how many claims have not been found for
1227 	 * a unsolved reference.
1228 	 */
1229 	protected Vector getUnsolvedReferenceRefNum()
1230 	{
1231 		Vector rc;
1232 
1233 		if (m_xmlSecurityFrameworkController == null)
1234 		{
1235 			rc = new Vector();
1236 		}
1237 		else
1238 		{
1239 			rc = ((XMLSecurityFrameworkController)m_xmlSecurityFrameworkController).
1240 				getUnsolvedReferenceRefNum();
1241 		}
1242 
1243 		return rc;
1244 	}
1245 
1246 
1247 /**************************************************************************************
1248  * public methods
1249  **************************************************************************************/
1250 
1251 	/******************************************************************************
1252 	 * action listener related methods.
1253 	 ******************************************************************************/
1254 
1255 	/*
1256 	 * action listening method.
1257 	 */
1258 	public void actionPerformed(ActionEvent e)
1259 	{
1260 		if (e.getSource().equals(m_startButton))
1261 		{
1262 			endMission();
1263 			startsUp();
1264 		}
1265 		if (e.getSource().equals(m_goButton))
1266 		{
1267 			if (m_parsingThread != null)
1268 			{
1269 				stepMode = false;
1270 				boolean notOver;
1271 				while ( notOver = m_parsingThread.nextStep())
1272 				{
1273 					if (stepMode) break;
1274 				}
1275 
1276 				if (!notOver) endMission();
1277 			}
1278 		}
1279 		if (e.getSource().equals(m_stepButton))
1280 		{
1281 			if (m_parsingThread != null)
1282 			{
1283 				if (!m_parsingThread.nextStep())
1284 				{
1285 					endMission();
1286 				}
1287 			}
1288 		}
1289 		if (e.getSource().equals(m_openButton))
1290 		{
1291 			openDocument();
1292 		}
1293 		if (e.getSource().equals(m_saveButton))
1294 		{
1295 			saveResult();
1296 		}
1297 		if (e.getSource().equals(m_batchButton))
1298 		{
1299 			openBatch();
1300 		}
1301 	}
1302 
1303 	/*
1304 	 * void-consturctor method
1305 	 */
1306 	public TestTool()
1307 	{
1308 	        getRootPane().putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);
1309 
1310         	try
1311         	{
1312         		m_currentDirectory = new File(System.getProperty("user.dir"));
1313 		}
1314 		catch(Exception e)
1315 		{
1316 			System.out.println("getProperty error :"+e);
1317 		}
1318 	}
1319 
1320 	/*
1321 	 * consturctor method with a specific connection URL
1322 	 */
1323 	public TestTool(String connecturl)
1324 	{
1325 		this();
1326 		m_unoURL = new String(connecturl);
1327 	}
1328 
1329 	public static void main(String argv[])
1330 	{
1331 		Dimension screenSize =
1332 			Toolkit.getDefaultToolkit().getScreenSize();
1333 
1334 		TestTool tt;
1335 
1336 		if (argv.length < 1)
1337 		{
1338 			System.out.println("Usage: java TestTool [javaTokenFile] [nssTokenPath] [xml file]?");
1339 			return;
1340 		}
1341 
1342 		boolean hasFile = false;
1343 		boolean hasBatch = false;
1344 		String fileName = null;
1345 
1346 		if (argv.length >= 3)
1347 		{
1348 			if (argv[2].startsWith("-b"))
1349 			{
1350 				fileName = argv[2].substring(2);
1351 				hasBatch = true;
1352 			}
1353 			else
1354 			{
1355 				fileName = argv[2];
1356 				hasFile = true;
1357 			}
1358 		}
1359 
1360 		tt = new TestTool();
1361 		tt.m_javaTokenFile = new String(argv[0]);
1362 		tt.m_nssTokenPath = new String(argv[1]);
1363 		tt.connectSO(null);
1364 
1365 		/* Set up a GUI framework */
1366 		JFrame myFrame = new JFrame("XML Security Components Tester");
1367 		myFrame.addWindowListener(
1368 			new WindowAdapter() {
1369 				public void windowClosing(WindowEvent e) {System.exit(0);}
1370 			}
1371 			);
1372 
1373 		myFrame.setContentPane(tt.buildUI(screenSize.width, screenSize.height));
1374 		myFrame.pack();
1375 		int w = screenSize.width-30;
1376 		int h = screenSize.height-30;
1377 		myFrame.setLocation(screenSize.width/2 - w/2,
1378 		screenSize.height/2 - h/2);
1379 		myFrame.setSize(w, h);
1380 		myFrame.setVisible(true);
1381 
1382 		if (hasFile)
1383 		{
1384 			tt.parseFile(new File(fileName));
1385 		}
1386 		else if (hasBatch)
1387 		{
1388 			tt.runBatch(new File(fileName));
1389 		}
1390 	}
1391 }
1392 
1393