1 /*************************************************************************
2  *
3  *  The Contents of this file are made available subject to the terms of
4  *  the BSD license.
5  *
6  *  Copyright 2000, 2010 Oracle and/or its affiliates.
7  *  All rights reserved.
8  *
9  *  Redistribution and use in source and binary forms, with or without
10  *  modification, are permitted provided that the following conditions
11  *  are met:
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
18  *     contributors may be used to endorse or promote products derived
19  *     from this software without specific prior written permission.
20  *
21  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28  *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29  *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30  *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31  *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  *
33  *************************************************************************/
34 
35 import com.sun.star.awt.Rectangle;
36 import com.sun.star.awt.XMessageBox;
37 import com.sun.star.awt.XMessageBoxFactory;
38 import com.sun.star.awt.XWindowPeer;
39 import com.sun.star.beans.NamedValue;
40 import com.sun.star.beans.XPropertySet;
41 import com.sun.star.container.XNameAccess;
42 import com.sun.star.frame.XModel;
43 import com.sun.star.lang.XComponent;
44 import com.sun.star.lang.XMultiComponentFactory;
45 import com.sun.star.lang.XMultiServiceFactory;
46 import com.sun.star.lang.XServiceInfo;
47 import com.sun.star.lang.XSingleComponentFactory;
48 import com.sun.star.lib.uno.helper.Factory;
49 import com.sun.star.lib.uno.helper.WeakBase;
50 import com.sun.star.registry.XRegistryKey;
51 import com.sun.star.ui.dialogs.XExecutableDialog;
52 import com.sun.star.ui.dialogs.XFolderPicker;
53 import com.sun.star.uno.UnoRuntime;
54 import com.sun.star.uno.XComponentContext;
55 import com.sun.star.util.CloseVetoException;
56 import com.sun.star.util.XChangesBatch;
57 import com.sun.star.util.XCloseable;
58 import java.util.HashMap;
59 import java.util.Iterator;
60 import java.util.Set;
61 import java.util.Vector;
62 import org.openoffice.XInstanceInspector;
63 
64 
65 /** The purpose of this class is to provide a factory for creating the service
66  * (<CODE>__getServiceFactory</CODE>) and writes the information into the given
67  * registry key (<CODE>__writeRegistryServiceInfo</CODE>).
68  */
69 public class Inspector{
70      public static final String sIDLDOCUMENTSUBFOLDER = "docs/common/ref/";
71 
72 
73     /** This class implements the method of the interface XInstanceInspector.
74      * Also the class implements the interfaces XServiceInfo, and XTypeProvider.
75      */
76     static public class _Inspector extends WeakBase implements XInstanceInspector, XServiceInfo{
77 
78         static private final String __serviceName = "org.openoffice.InstanceInspector";
79         private HashMap aApplicationHashMap = new HashMap();
80         private String sTitle = "Object Inspector";
81         private Vector aHiddenDocuments = new Vector();
82 //        private String[] sApplicationDocUrls = new String[]{"private:factory/swriter", "private:factory/scalc", "private:factory/simpress", "private:factory/sdraw", "private:factory/sbase"};
83 //        private String[] sApplicationDocNames = new String[]{"Text Document", "Spreadsheet", "Presentation", "Drawing", "Database"};
84         private XComponentContext m_xComponentContext;
85         private HashMap aInspectorPanes = new HashMap();
86         private XDialogProvider m_oSwingDialogProvider;
87         private TDocSupplier oTDocSupplier;
88         private Introspector m_oIntrospector = null;
89         // TODO: improve these strings:
90         private static final String sWRONGINSTALLATIONPATH = "Your selected path does not refer to an SDK-Installation!";
91         /** Creates a new instance of Dialog */
92         public _Inspector(XComponentContext _xComponentContext) {
93             m_xComponentContext = _xComponentContext;
94             m_oIntrospector = Introspector.getIntrospector(m_xComponentContext);
95             aApplicationHashMap.put("private:factory/swriter", "Text Document");
96             aApplicationHashMap.put("private:factory/scalc", "Spreadsheet");
97             aApplicationHashMap.put("private:factory/simpress", "Presentation");
98             aApplicationHashMap.put("private:factory/sdraw", "Drawing");
99             aApplicationHashMap.put("private:factory/smath", "Formula");
100             m_oSwingDialogProvider = new SwingDialogProvider(this, sTitle);
101 //            aApplicationHashMap.put("private:factory/sbase", "Database");
102         }
103 
104 
105         public XComponentContext getXComponentContext(){
106             return m_xComponentContext;
107         }
108 
109 
110         public HashMap getInspectorPages(){
111             return aInspectorPanes;
112         }
113 
114 
115         protected String getSDKPath(){
116         String sRetPath = "";
117         try{
118             XNameAccess xNameAccess  = getConfigurationAccess("org.openoffice.inspector.ObjectInspector", true);
119             XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xNameAccess);
120             sRetPath = (String) xPropertySet.getPropertyValue("SDKPath");
121         }catch( Exception exception ) {
122             exception.printStackTrace(System.out);
123         }
124         return sRetPath;
125         }
126 
127 
128         public String getIDLPath(){
129             String sRetPath = getSDKPath();
130             if (m_oIntrospector.isValidSDKInstallationPath(sRetPath)){
131                 sRetPath = m_oIntrospector.addToPath(sRetPath, sIDLDOCUMENTSUBFOLDER);
132             }
133             else{
134                 sRetPath = "";
135             }
136             return sRetPath;
137         }
138 
139 
140         public void openIdlFileforSelectedNode(){
141             InspectorPane oInspectorPane = m_oSwingDialogProvider.getSelectedInspectorPage();
142             if (oInspectorPane != null){
143                 XUnoNode oUnoNode = oInspectorPane.getSelectedNode();
144                 if (oUnoNode != null){
145                     String sPath = getIDLPath();
146                     oUnoNode.openIdlDescription(sPath);
147                 }
148             }
149         }
150 
151 
152         public void assignSDKPath() {
153         try {
154             String sInstallationFolder = "";
155             Object oFolderPicker = m_xComponentContext.getServiceManager().createInstanceWithContext("com.sun.star.ui.dialogs.FolderPicker", m_xComponentContext);
156             XFolderPicker xFolderPicker = (XFolderPicker) UnoRuntime.queryInterface(XFolderPicker.class, oFolderPicker);
157             XExecutableDialog xExecutable = (XExecutableDialog) UnoRuntime.queryInterface(XExecutableDialog.class, oFolderPicker);
158             XComponent xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, oFolderPicker);
159             String sPath = getSDKPath();
160             if (!sPath.equals("")){
161                 xFolderPicker.setDisplayDirectory(sPath);
162             }
163             xFolderPicker.setTitle("Add the Path to your SDK installation");
164             short nResult = xExecutable.execute();
165             if (nResult == com.sun.star.ui.dialogs.ExecutableDialogResults.OK){
166                 sInstallationFolder = xFolderPicker.getDirectory();
167                 if (m_oIntrospector.isValidSDKInstallationPath(sInstallationFolder)){
168                     XNameAccess xNameAccess = getConfigurationAccess(true);
169                     XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xNameAccess);
170                     xPropertySet.setPropertyValue("SDKPath", sInstallationFolder);
171                     XChangesBatch xBatch = (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class, xNameAccess);
172                     xBatch.commitChanges();
173                 }
174                 else{
175                     XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xFolderPicker);
176                     Object oWindow = xPropertySet.getPropertyValue("Window");
177                     XWindowPeer xWindowPeer = (XWindowPeer) UnoRuntime.queryInterface(XWindowPeer.class, oWindow);
178                     showErrorMessageBox(xWindowPeer, sTitle, sWRONGINSTALLATIONPATH);
179                     assignSDKPath();
180                 }
181             }
182             xComponent.dispose();
183         }catch( Exception exception ) {
184             exception.printStackTrace(System.out);
185         }}
186 
187 
188         public void showErrorMessageBox(XWindowPeer _xWindowPeer, String _sTitle, String _sMessage){
189         try {
190             Object oToolkit = m_xComponentContext.getServiceManager().createInstanceWithContext("com.sun.star.awt.Toolkit", m_xComponentContext);
191             XMessageBoxFactory xMessageBoxFactory = (XMessageBoxFactory) UnoRuntime.queryInterface(XMessageBoxFactory.class, oToolkit);
192             Rectangle aRectangle = new Rectangle();
193             XMessageBox xMessageBox = xMessageBoxFactory.createMessageBox(_xWindowPeer, aRectangle, "errorbox", com.sun.star.awt.MessageBoxButtons.BUTTONS_OK, _sTitle, _sMessage);
194             XComponent xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, xMessageBox);
195             if (xMessageBox != null){
196                 short nResult = xMessageBox.execute();
197                 xComponent.dispose();
198             }
199         } catch (com.sun.star.uno.Exception ex) {
200             ex.printStackTrace(System.out);
201         }}
202 
203 
204         public void inspect(java.lang.Object _oUserDefinedObject, String _sTitle) throws com.sun.star.uno.RuntimeException {
205         try {
206             int nPageIndex = m_oSwingDialogProvider.getInspectorPageCount();
207             SwingTreeControlProvider oSwingTreeControlProvider = new SwingTreeControlProvider(m_oSwingDialogProvider);
208             InspectorPane oInspectorPane = new InspectorPane(getXComponentContext(), m_oSwingDialogProvider, oSwingTreeControlProvider, getSourceCodeLanguage());
209             oInspectorPane.inspect(_oUserDefinedObject, _sTitle);
210             getInspectorPages().put(_sTitle, oInspectorPane);
211             m_oSwingDialogProvider.show(nPageIndex);
212         }catch( Exception exception ) {
213             exception.printStackTrace(System.out);
214         }}
215 
216 
217         public void inspectOpenEmptyDocument(String _sApplicationDocUrl){
218             XComponent xComponent = getTDocSupplier().openEmptyDocument(_sApplicationDocUrl);
219             String sRootTitle = (String) aApplicationHashMap.get(_sApplicationDocUrl);
220             inspect(xComponent, sRootTitle);
221             aHiddenDocuments.add(xComponent);
222         }
223 
224 
225         public void inspectOpenDocument(String _sTDocUrl){
226             String sTreeNodeName = getTDocSupplier().getTitleByTDocUrl(_sTDocUrl);
227             XModel xTDocModel = getTDocSupplier().getXModelByTDocUrl(_sTDocUrl);
228             inspect(xTDocModel, sTreeNodeName);
229         }
230 
231 
232         public void inspectSelectedNode(){
233             InspectorPane oInspectorPane = m_oSwingDialogProvider.getSelectedInspectorPage();
234             if (oInspectorPane != null){
235                 XUnoNode oUnoNode = oInspectorPane.getSelectedNode();
236                 Object oUnoObject = oUnoNode.getUnoObject();
237                 if (oUnoObject != null){
238                     String sNodeDescription = UnoNode.getNodeDescription(oUnoObject);
239                     inspect(oUnoObject, sNodeDescription);
240                 }
241             }
242         }
243 
244 
245         public void addSourceCodeOfSelectedNode(){
246             InspectorPane oInspectorPane = m_oSwingDialogProvider.getSelectedInspectorPage();
247             if (oInspectorPane != null){
248                 oInspectorPane.addSourceCodeOfSelectedNode();
249             }
250         }
251 
252 
253         public void invokeSelectedMethod(){
254             InspectorPane oInspectorPane = m_oSwingDialogProvider.getSelectedInspectorPage();
255             if (oInspectorPane != null){
256                 oInspectorPane.invokeSelectedMethodNode();
257             }
258         }
259 
260 
261         public void setSourceCodeLanguage(final int _nLanguage){
262         try{
263             String sLanguage = "Java";
264             XNameAccess xNameAccess  = getConfigurationAccess("org.openoffice.inspector.ObjectInspector", true);
265             XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xNameAccess);
266             switch (_nLanguage){
267                 case XLanguageSourceCodeGenerator.nJAVA:
268                     sLanguage = "Java";
269                     break;
270                 case XLanguageSourceCodeGenerator.nCPLUSPLUS:
271                     sLanguage = "CPlusPlus";
272                     break;
273                 case XLanguageSourceCodeGenerator.nBASIC:
274                     sLanguage = "Basic";
275                     break;
276                 default:
277                     System.out.println("Warning: Sourcecode language is not defined!");
278             }
279             xPropertySet.setPropertyValue("Language", sLanguage);
280             XChangesBatch xBatch = (XChangesBatch) UnoRuntime.queryInterface(XChangesBatch.class, xNameAccess);
281             xBatch.commitChanges();
282             for (int i = 0; i < m_oSwingDialogProvider.getInspectorPageCount(); i++){
283                 m_oSwingDialogProvider.getInspectorPage(i).convertCompleteSourceCode(_nLanguage);
284             }
285         }catch( Exception exception ) {
286             exception.printStackTrace(System.out);
287         }}
288 
289 
290         private TDocSupplier getTDocSupplier(){
291             if (oTDocSupplier == null){
292                 oTDocSupplier = new TDocSupplier(m_xComponentContext);
293             }
294             return oTDocSupplier;
295         }
296 
297         public String[] getTDocUrls(){
298             return getTDocSupplier().getTDocUrls();
299         }
300 
301 
302         public String[] getTDocTitles(String[] _sTDocUrls){
303             return getTDocSupplier().getTDocTitles(_sTDocUrls);
304         }
305 
306 
307         public String[][] getApplicationUrls(){
308             Set aSet = aApplicationHashMap.keySet();
309             String[][] sReturnList = new String[aSet.size()][];
310             int n= 0;
311             for ( Iterator i = aSet.iterator(); i.hasNext(); ){
312                 String[] sSingleApplication = new String[2];
313                 sSingleApplication[0] = (String) i.next();
314                 // assign the title in the second index
315                 sSingleApplication[1] = (String) aApplicationHashMap.get(sSingleApplication[0]);
316                 sReturnList[n++] = sSingleApplication;
317             }
318             return sReturnList;
319         }
320 
321 
322         public void disposeHiddenDocuments(){
323             int nHiddenCount = aHiddenDocuments.size();
324             if (nHiddenCount > 0){
325                 for (int i = nHiddenCount - 1; i >= 0; i--){
326                     XComponent xComponent = (XComponent) aHiddenDocuments.get(i);
327                     if (xComponent != null){
328                         try {
329                             XCloseable xCloseable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, xComponent);
330                             xCloseable.close(true);
331                             aHiddenDocuments.remove(i);
332                         } catch (CloseVetoException ex) {
333                             ex.printStackTrace();
334                         }
335                     }
336                 }
337             }
338         }
339 
340 
341         public static String[] getServiceNames() {
342             String[] sSupportedServiceNames = { __serviceName };
343             return sSupportedServiceNames;
344         }
345 
346         // Implement the interface XServiceInfo
347         /** Get all supported service names.
348          * @return Supported service names.
349          */
350         public String[] getSupportedServiceNames() {
351             return getServiceNames();
352         }
353 
354         // Implement the interface XServiceInfo
355         /** Test, if the given service will be supported.
356          * @param sService Service name.
357          * @return Return true, if the service will be supported.
358          */
359         public boolean supportsService( String sServiceName ) {
360             return sServiceName.equals( __serviceName );
361         }
362 
363         // Implement the interface XServiceInfo
364         /** Get the implementation name of the component.
365          * @return Implementation name of the component.
366          */
367         public String getImplementationName() {
368             return _Inspector.class.getName();
369         }
370 
371 
372         private int getSourceCodeLanguage(){
373         int nLanguage = XLanguageSourceCodeGenerator.nJAVA;
374         try{
375             XNameAccess xNameAccess  = getConfigurationAccess("org.openoffice.inspector.ObjectInspector", false);
376             String sLanguage = (String) xNameAccess.getByName("Language");
377             if (sLanguage.toUpperCase().equals("JAVA")){
378                 nLanguage = XLanguageSourceCodeGenerator.nJAVA;
379             }
380             else if (sLanguage.toUpperCase().equals("BASIC")){
381                 nLanguage = XLanguageSourceCodeGenerator.nBASIC;
382             }
383             else if (sLanguage.toUpperCase().equals("CPLUSPLUS")){
384                 nLanguage = XLanguageSourceCodeGenerator.nCPLUSPLUS;
385             }
386             else{
387                 System.out.println("Warning: Sourcecode language " + sLanguage + " is not defined!");
388             }
389             m_oSwingDialogProvider.selectSourceCodeLanguage(nLanguage);
390         }catch( Exception exception ) {
391             exception.printStackTrace(System.out);
392         }
393             return nLanguage;
394         }
395 
396 
397         public XNameAccess getConfigurationAccess(boolean _bUpdate){
398             return getConfigurationAccess("org.openoffice.inspector.ObjectInspector", _bUpdate);
399         }
400 
401 
402         public XNameAccess getConfigurationAccess(String _sNodePath, boolean update) {
403         XNameAccess xNameAccess = null;
404         try {
405             String sAccess = "";
406             if (update) {
407                 sAccess = "com.sun.star.configuration.ConfigurationUpdateAccess";
408             }
409             else{
410                 sAccess = "com.sun.star.configuration.ConfigurationAccess";
411             }
412             XMultiComponentFactory xMCF = m_xComponentContext.getServiceManager();
413             Object oDefaultProvider = xMCF.createInstanceWithContext("com.sun.star.configuration.DefaultProvider", this.getXComponentContext());
414             XMultiServiceFactory xMSFCfg = (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, oDefaultProvider);
415             Object oAccess = xMSFCfg.createInstanceWithArguments(sAccess, new Object[]{new NamedValue("nodepath", _sNodePath)});
416             xNameAccess = (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class, oAccess);
417         } catch (com.sun.star.uno.Exception e) {
418         }
419         return xNameAccess;
420         }
421 
422 
423     }
424 
425 // end of inner class
426 
427 
428     /**
429      * Gives a factory for creating the service.
430      * This method is called by the <code>JavaLoader</code>
431      * <p>
432      * @return  returns a <code>XSingleComponentFactory</code> for creating
433      *          the component
434      * @param   sImplName the name of the implementation for which a
435      *          service is desired
436      * @see     com.sun.star.comp.loader.JavaLoader
437      */
438     public static XSingleComponentFactory __getComponentFactory( String sImplName )
439     {
440         XSingleComponentFactory xFactory = null;
441         if ( sImplName.equals( _Inspector.class.getName() ) )
442             xFactory = Factory.createComponentFactory(_Inspector.class, _Inspector.getServiceNames());
443         if ( xFactory == null )
444             xFactory = InspectorAddon.__getComponentFactory(sImplName);
445         return xFactory;
446     }
447 
448     /**
449      * Writes the service information into the given registry key.
450      * This method is called by the <code>JavaLoader</code>
451      * <p>
452      * @return  returns true if the operation succeeded
453      * @param   regKey the registryKey
454      * @see     com.sun.star.comp.loader.JavaLoader
455      */
456     public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) {
457         return (Factory.writeRegistryServiceInfo(_Inspector.class.getName(), _Inspector.getServiceNames(), regKey)
458                 && InspectorAddon.__writeRegistryServiceInfo(regKey));
459     }
460 }
461 
462