GI 3.9 DeveloperGuide
GI 3.9 DeveloperGuide
Important Information
SOME TIBCO SOFTWARE EMBEDS OR BUNDLES OTHER TIBCO SOFTWARE. USE OF SUCH EMBEDDED OR BUNDLED TIBCO SOFTWARE IS SOLELY TO ENABLE THE FUNCTIONALITY (OR PROVIDE LIMITED ADD-ON FUNCTIONALITY) OF THE LICENSED TIBCO SOFTWARE. THE EMBEDDED OR BUNDLED SOFTWARE IS NOT LICENSED TO BE USED OR ACCESSED BY ANY OTHER TIBCO SOFTWARE OR FOR ANY OTHER PURPOSE. USE OF TIBCO SOFTWARE AND THIS DOCUMENT IS SUBJECT TO THE TERMS AND CONDITIONS OF A LICENSE AGREEMENT FOUND IN EITHER A SEPARATELY EXECUTED SOFTWARE LICENSE AGREEMENT, OR, IF THERE IS NO SUCH SEPARATE AGREEMENT, THE CLICKWRAP END USER LICENSE AGREEMENT WHICH IS DISPLAYED DURING DOWNLOAD OR INSTALLATION OF THE SOFTWARE (AND WHICH IS DUPLICATED IN TIBCO GENERAL INTERFACE INSTALLATION) OR IF THERE IS NO SUCH SOFTWARE LICENSE AGREEMENT OR CLICKWRAP END USER LICENSE AGREEMENT, THE LICENSE(S) LOCATED IN THE "LICENSE" FILE(S) OF THE SOFTWARE. USE OF THIS DOCUMENT IS SUBJECT TO THOSE TERMS AND CONDITIONS, AND YOUR USE HEREOF SHALL CONSTITUTE ACCEPTANCE OF AND AN AGREEMENT TO BE BOUND BY THE SAME. This document contains confidential information that is subject to U.S. and international copyright laws and treaties. No part of this document may be reproduced in any form without the written authorization of TIBCO Software Inc. TIB, TIBCO, TIBCO Adapter, Predictive Business, Information Bus, The Power of Now, TIBCO General Interface, TIBCO General Interface Framework, TIBCO General Interface Builder, TIBCO General Interface Performance Profiler, and TIBCO General Interface Test Automation Kit are either registered trademarks or trademarks of TIBCO Software Inc. in the United States and/or other countries. EJB, Java EE, J2EE, and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All other product and company names and marks mentioned in this document are the property of their respective owners and are mentioned for identification purposes only. THIS SOFTWARE MAY BE AVAILABLE ON MULTIPLE OPERATING SYSTEMS. HOWEVER, NOT ALL OPERATING SYSTEM PLATFORMS FOR A SPECIFIC SOFTWARE VERSION ARE RELEASED AT THE SAME TIME. SEE THE README.TXT FILE FOR THE AVAILABILITY OF THIS SOFTWARE VERSION ON A SPECIFIC OPERATING SYSTEM PLATFORM. THIS DOCUMENT IS PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THIS DOCUMENT COULD INCLUDE TECHNICAL INACCURACIES OR TYPOGRAPHICAL ERRORS. CHANGES ARE PERIODICALLY ADDED TO THE INFORMATION HEREIN; THESE CHANGES WILL BE INCORPORATED IN NEW EDITIONS OF THIS DOCUMENT. TIBCO SOFTWARE INC. MAY MAKE IMPROVEMENTS AND/OR CHANGES IN THE PRODUCT(S) AND/OR THE PROGRAM(S) DESCRIBED IN THIS DOCUMENT AT ANY TIME. THE CONTENTS OF THIS DOCUMENT MAY BE MODIFIED AND/OR QUALIFIED, DIRECTLY OR INDIRECTLY, BY OTHER DOCUMENTATION WHICH ACCOMPANIES THIS SOFTWARE, INCLUDING BUT NOT LIMITED TO ANY RELEASE NOTES AND "READ ME" FILES. U.S. Patent No. 8,136,109 Copyright 2001-2012 TIBCO Software Inc. ALL RIGHTS RESERVED. TIBCO Software Inc. Confidential Information
Using Palettes
This section describes the General Interface Builder palettes that you use as you work with your application.
For more information on projects, see Managing Projects. For definitions of toolbar buttons, see Project Files Palette Toolbar.
These object libraries not only reduce the time required to build applications, they also allow object behavior and look-and-feel to be easily customized. Prototype objects can be dragged from the Component Libraries palette to any object in the work area or to the Component Hierarchy palette. A new object of the selected type is created as a child of the object where it's dropped if the parent object accepts children. You can also create, manage, and share your own libraries of components. Saving a component definition to the workspace /prototypes directory adds it to the User folder in the Component Libraries palette. The custom component can then be reused like any other prototype component. The Addins folder contains any prototypes defined in an add-in, such as Charting. You can also create your own custom add-ins. Add-ins must be enabled on the Add-Ins panel before they display in the Addins folder. For more information, see General Interface Component Guide. For more information on components and tutorial on custom add-ins, see the General Interface Component Guide.
Objects can contain other objects. For example, a LayoutGrid component could include Text Box, Label, and Button objects, as well as other components. Applications usually consist of multiple components that work together using JavaScript logic. Using the Component Hierarchy palette, you can select objects and then modify them using other palettes, such as Properties Editor palette, Events Editor palette, and so on. Once you've defined a component or object, you can also clone it to quickly make multiple copies. Objects can also be exported to reuse in other applications or imported from another project into the current one. For more information about working with components, see General Interface Component Guide. Use Ctrl+click to select multiple components. Use Shift+click to choose a range of components. For definitions of toolbar buttons, see Component Hierarchy Palette Toolbar.
To modify a property, do one of the following in the Properties Editor palette: Type a value in the Value column. Right-click and choose a dynamic property value from the menu, if available. For more information, see Dynamic Properties Files. Type a dynamic property key or a properties bundle key in the Value column. See Dynamic Properties Files and Properties Bundle Files. Click the down arrow in the Value column and select a value from the list, if available. To learn more about properties in the Properties Editor palette, hover the mouse over the property name or see General Interface GUI Property Reference (Help > API Documentation > GUI Property Reference). To modify a common property for multiple components, select multiple components in the Component Hierarchy palette using Ctrl+click or Shift+click and set the property value. In the following example, the three selected components have a common width property of 120. If property values are different, [multiple values] displays in the value field.
To learn more about events in the Events Editor palette, hover the mouse over the event name or see General Interface GUI Event Reference (Help > API Documentation > GUI Event Reference). For more information, see General Interface Component Guide and Associating Code with an Event.
HTML attributes change how the component is rendered when it's displayed in the browser. After using the Attributes Editor palette, you can view your changes in the Rendered HTML (Read Only) view of the work area. If, for example, you add an attribute of name foo and value bar to a block, this HTML markup is added to the rendered HTML markup for the component selected in the Component Hierarchy palette:
<div id="_jsx_1_3" label="block" class="jsx30block" *foo="bar"* style="position:relative;width:490px;height:516px; font-size:10px;;overflow:auto;font-family:Verdana;z-index:1; text-align:left;display:block;"/> </div>
10
4. Type a value in the Value field. 5. Click the Add Attribute button
To change an existing XSL parameter, select the Value field, change the value, and press Enter. To remove a parameter, right-click a row and choose Remove Parameter. For example, the XSL for the Matrix List prototype defines two parameters: jsx_rowbg1 and jsx_rowbg2. These parameters control the background color of odd and even numbered rows respectively.
To learn more about XSL parameters, see General Interface XSL Parameter Reference (Help > API Documentation > XSL Parameter Reference).
11
For more information on caching, see Handling Application Data. For definitions of toolbar buttons, see Local Data Cache Palette Toolbar.
12
The System Log palette has the following features: Docking options Adjustable log levels, such as OFF, FATAL, ERROR, WARN, INFO, DEBUG, or TRACE Support for sound for messages Color coding of messages, such as red for error messages For definitions of toolbar buttons, see System Log Palette Toolbar. For more information about logging, see Logging and Application Monitors.
Firefox requires a plug-in that can play .wav files. 3. Save logger.xml.
13
The IDE Settings dialog has several panels: IDE Settings Panel IDE Hot Keys Panel Paths Panel GIPP and GITAK Panel This section discusses some but not all of the available options. For more information, see IDE Settings Dialog.
Character Encoding
General Interface Builder provides support for writing files in a specified character encoding, such as UTF-8 or UTF-16. The ability to choose a character encoding is particularly useful for developing and localizing applications for multilingual environments. General Interface Builder allows you to specify an encoding for all project files, as well as separately specify an encoding for XML files.
Copyright TIBCO Software Inc. All Rights Reserved.
14
General Interface Builder settings in the IDE Settings dialog allow you to: Specify character encoding for all project files Specify character encoding for XML files Specify whether to add character encodings to XML declarations Specify the output line separator Test the specified encodings to verify they can be written For applications loaded from the local disk, such as General Interface Builder, Firefox reads non-XML files that are encoded in a standard 8-bit encoding. Firefox can read local XML files in any encoding supported by the host system only if the encoding is included in the XML declaration.
15
1. Double-click a row in the Menu list. 2. Press the keys you want for the hot key, such as Ctrl+Alt+m. 3. Click Set. 4. Click Save to save the changes and close the dialog or click Apply. 5. Use the browser reload button to restart General Interface Builder for the changes to take effect. To revert to the default hot key, double-click a row and choose Use Default.
Paths Panel
On the Paths panel, you can set the workspace path for your projects and the HTTP base path for running applications from a local HTTP server.
Workspace
The workspace is the directory that contains your projects, custom add-ins and prototypes, and your user settings for General Interface Builder. To modify the workspace path, 1. Open the IDE Settings dialog and click the Paths button. 2. Click the Browse button next to the Workspace field to open the Choose Folder dialog. 3. Navigate to a folder, select it, and click Choose. Click Choose again to close the Choose Folder dialog. You can also use the New Folder button to create a new folder. 4. Click Save to save the changes and close the IDE Settings dialog or click Apply. 5. Click OK at the Restart Required prompt and use the browser reload button to restart General Interface Builder.
HTTP Base
The path in the HTTP Base field is used when you select Project > Run Project From HTTP. To use this feature, you must have an HTTP web server, such as Apache, hosting both the General Interface installation directory and your workspace directory. To add an HTTP base, enter the base URI for the General Interface directory on a local HTTP server. If this field is empty and you choose Project > Run Project From HTTP, you are prompted to enter a path. If the relative path between the workspace directory and the General Interface directory isn't the same on the HTTP server as on disk, you must enter the relative path to the workspace directory in the WS Path field.
16
Chat Panel
On the Chat panel, you can specify server and login settings for the Jabber client in General Interface Builder. See Jabber Support.
To hide all the palettes, click the Show Edit Pane button Builder taskbar.
Managing Projects
All development work in General Interface Builder is done in a project in the workspace. Projects are collections of files you create and edit in General Interface Builder. Project files are displayed in the Project Files palette and stored in the workspace.
Choosing a Workspace
The workspace is the directory that contains your projects, custom add-ins, custom prototypes, and your user settings for General Interface Builder. The first time General Interface Builder launches after installation, a dialog prompts you to create or select a workspace directory. You can create a new directory, select an existing directory, or choose the default workspace directory. The default workspace location is C:\Documents and Settings\username\My Documents\TibcoGI. You can use multiple workspaces for your projects, as well as change workspaces. For more information, see General Interface Getting Started.
Changing a Workspace
You can keep all of your projects in one workspace or use multiple workspaces. You can modify the workspace location in the IDE Settings dialog. See Workspace.
17
Creating Projects
When you create a project, default files are created and opened in the work area: logic.js and appCanvas.xml. The JavaScript file, logic.js, is an empty file that you can add JavaScript code to. The default GUI component file, appCanvas.xml, is where you can begin designing your application user interface. To create a project, complete these steps: 1. Choose Project > New Project or click the Create a New Project link in the Welcome screen (Help > Welcome Screen) to open the new project wizard. 2. Choose General Interface Application as the project type, and click Next.
18
A new project is loaded in the browser window. Two default, empty files are open in the central work area. While building this sample application, all project data is stored locally in browser memory. The application is not automatically saved to the file system. Save the project before you close or refresh the browser window. If you don't save the project, the data is lost.
The top-level project folder has the same name as your project. All project folders include the default subdirectories and files listed in the following table. This default structure can be modified and additional folders can be created as needed. For example, you might create folders for image, WSDL, and CSS files.
19
Project Files
config.xml
Description Contains application configuration data, such as project settings and file locations. See Modifying Project Settings. Launches the application in the web browser. Use this file only during development, not at runtime. during development, not at runtime.
launch.html
launch_in_ide.html Launches the application in General Interface Builder. Use this file only
To access project files and folders, click the JSXAPPS/project_name link in the General Interface Builder taskbar, located in the lower left area of the IDE.
Project Folders
Description
components Contains the XML files for application components. Each component has an associated XML file with object definitions. For component files, use the .xml extension. When you create a new project, a default component named appCanvas.xml is created in this folder. See General Interface Component Guide. js Contains included JavaScript files for your application. For JavaScript files, use the .js extension. When you create a new project, a default file named logic.js is created in this folder. See Adding and Debugging JavaScript Code. Contains dynamic properties XML files. For dynamic properties files, use the .xml extension. See Dynamic Properties Files. Contains mapping rules XML files for connecting to web services. Rules files define the mappings between GUI components and SOAP message elements. For mapping rules files, use the .xml extension. See Basic Steps for Communicating with Data Services. Contains any XML files with content data, such as default values, for the application. For XML files, use the .xml extension. Contains any XSL files used for transforming application data. For XSL files, use the .xsl extension. These project folder names are conventions only and not mandatory.
jss rules
xml xsl
Saving Projects
When you save project files, General Interface Builder saves them to a project directory in the JSXAPPS directory in the specified workspace directory. For example, workspace /JSXAPPS/project_name. For more information on workspaces, see General Interface Getting Started. There are several ways to save files in a project: Right-click a file tab in the work area and choose Save, Save and Reload, or Save As. Choose File > Save, Save and Reload, Save As, or Save All.
Copyright TIBCO Software Inc. All Rights Reserved.
20
Choose File > Save, Save and Reload, Save As, or Save All. For a local data cache XML file, right-click a file tab in the work area and choose Save to Cache or Save a Copy to Disk. For menu definitions, see File Menu.
Running Projects
There are several ways to run a project: Choose Project > Run Project. Choose Project > Run Project from HTTP. Double-click the default launch file, workspace/project_dir/launch.html, which is generated when you create the project. Use this file only during development, not during deployment. To run deployed applications, see Deploying Applications.
Opening Projects
There are several ways to open a project: Choose the Open an Existing Project link in the Welcome screen (Help > Welcome Screen) and choose a project from the list. Choose Project > User Projects and choose a project from the list. To open a General Interface sample project, choose Project > User Projects > Samples and choose a sample project from the list. Choose Project > Recent Projects and choose a recently opened project from the list. Double-click the default General Interface Builder launch file, workspace/ project_dir /launch_in_ide.html, which is generated when you create the project. Use this file to launch the project only during development, not at runtime. You can also open multiple instances of the same project in different browsers, such as Internet Explorer and Firefox. However, because each instance is sharing the same preferences and settings files, competing changes to General Interface Builder preferences may not be persisted.
Closing Projects
To close a project, simply close the browser.
21
Deploying Projects
To deploy a project, set deployment options on the Deployment panel of the Project Settings dialog. Use the Deployment Utility to create a hyperlink to the deployed application. Then copy your application files and General Interface software to an HTTP or HTTPS web server. For more information, see the following: Deployment Panel Deploying Applications
22
The Project Settings dialog has several panels: Deployment Panel Add-Ins Panel Classpath Panel Legacy Settings Panel For more information on available options in the Project Settings dialog, see Project Settings Dialog.
Deployment Panel
Settings on this panel control the behavior of the deployed application. For definitions of options not discussed here, see Project Settings Dialog. For more information on deployment, see Deploying Applications.
Namespace
The General Interface runtime creates a single instance of a jsx3.app.Server for each loaded application. The application namespace, which is a unique JavaScript identifier for the jsx3.app.Server instance, provides access to the jsx3.app.Server instance. When specifying a namespace, it's recommended that you use the reverse-domain naming convention with the dot symbol (.). For example com.tibco.APP. Using the reverse-domain naming convention reduces the likelihood that other JavaScript code will interfere with your application. To specify the namespace, complete these steps: 1. Choose Project > Project Settings >Deployment to open the Deployment panel of the Project Settings dialog. 2. Type the namespace in the Namespace field. For example, set the namespace to
eg.chart.APP.
You can also override the namespace per deployment using the jsxappns deployment parameter. See Deployment Parameters.
Mode
The deployment mode for the deployed application can be set to Live or Static mode. Select Live mode if the application needs to be online and is connected over HTTP/S to a server for online data access. Select Static mode when working offline. When in offline mode, the application can't access a server. Data is static and is referenced using static URLs stored in rules files. Choose Static when developing and testing an application offline or when a back-end web service isn't available. The Mode setting is used by the j sx3.net.Service class.
23
bubbles up to the HTML body element is sent to the application. Even if the focus is in the browser window and not in the General Interface application, the application receives the hot key and responds to it. Choose this option for deployment of standalone console applications. See Deploying as a Full Console Application. When the Body Hot Keys option is unchecked, hot keys only function if the focus is in the General Interface application. This deployment choice prevents your application from responding to hot keys initiated in other General Interface applications on the page. Choose this option for deployment of non-console applications that are a portion of a web page. See Deploying as a Non-Console Application.
onLoad Script
Enter one or more JavaScript statements that you want executed when the application initializes. For example, you might want to execute a main method, communicate with a server, create controller objects by instantiating a controller class, or create the state of the application. For more information, see Executing Code When the Application Loads and Deployment Panel.
onUnload Script
Enter one or more JavaScript statements that you want executed when the browser window is unloaded. The onUnload event allows you to save user state and do any final cleanup before exiting. For more information, see Executing Code When the Application Unloads and Deployment Panel. For descriptions of other options on this panel, see Deployment Panel. For more information on deployment, see Deploying Applications.
Add-Ins Panel
Use the Add-Ins panel to enable the Charting add-in or custom add-ins for a project. Add-ins are disabled by default to accelerate load time of General Interface Builder and General Interface applications.
Enabling Add-ins
To enable add-ins, 1. Choose Project > Project Settings to open the Project Settings dialog and click Add-Ins. 2. Check the add-in you'd like to enable on the Add-Ins panel. 3. Click Save to save the changes and close the dialog or click Apply. 4. Click OK at the Restart Required prompt and use the browser reload button to restart General Interface Builder. After add-ins are enabled, their prototypes are available in the Component Libraries palette in General Interface Builder. For more information on the Charting add-in, see General Interface Component Guide.
Custom Add-ins
For custom add-ins to display on the Add-Ins panel, they must be saved to the JSX/addins or workspace/addins directory. Typically, add-ins to be used by a team of developers would be saved to the JSX/addins directory and posted by an administrator to a location accessible to the team. Add-ins for individual use can be saved to the workspace/addins directory.
Copyright TIBCO Software Inc. All Rights Reserved.
24
Classpath Panel
The project class path is used by General Interface to find custom classes that are dynamically loaded by your application. To add a class path, complete the following steps: 1. Click in the Path field and type the path to the classes. The class path is relative to the project directory. For example, entering js/ as the path would load the specified classes in the workspace /JSXAPPS/project_dir/js directory. 2. Press the Tab key and type the packages to load in the Packages field. For example, com.tibco.*. 3. Press Enter to commit the class path. 4. Click Save to save the changes and close the dialog or click Apply. 5. Use the browser reload button to restart General Interface Builder for the changes to take effect. To delete a class path, click the Delete button Path
js/
Packages
com.tibco.*
Description Loads classes with three words beginning with com.tibco from the directory workspace/JSXAPPS/project_dir/js. For example, this would load the class file workspace /JSXAPPS/project_dir/js/com/tibco/Object.js.
js-ext/
com.tibco.ext.* Loads classes with four words beginning with com.tibco.ext from the directory workspace/JSXAPPS/project_dir/js-ext. For example, this would load the class file workspace /JSXAPPS/project_dir/js-ext/com/tibco/ext/Object.js. com.foo.**
js-foo/
Loads all nested classes of com.foo from the directory workspace /JSXAPPS/project_dir/js-foo/. Loads classes with four words beginning with com.foo from the directory workspace/JSXAPPS/project_dir/js-foo2.
js-foo2/ com.foo.*.*
25
CSS (Cascading Style Sheets) Dynamic properties Properties bundle Mapping rules files GIPP test cases GITAK test cases
26
Grid View
The Grid view is available for dynamic properties files and properties bundle files. You can use dynamic properties files, which are XML resource files, to create custom properties for components. Properties bundle files are XML resource files used to localize your application for a specific language and country. For more information, see Dynamic Properties Files. See Properties Bundle Files and Internationalizing and Localizing Applications.
Source View
The Source view is available for all file types and displays the editable source for XML files and text files, such as JavaScript and CSS files. For components, the Source view displays the XML source of the component serialization file.
27
When running General Interface Builder in HTML and XHTML mode, well-formed HTML, which is XHTML, is pretty-printed in the Rendered HTML (Read Only) view. If the markup isn't well-formed, pretty printing isn't used and a parsing error displays in the System Log palette. For example, if you entered HTML without a closing element in the Text/HTML property for a label, such as <b>My Label, a mismatched tag error message displays in the System Log palette and the Rendered HTML (Read Only) view isn't pretty-printed. If you entered valid XHTML with open and close elements, such as <b>My Label</b>, no error is reported and the Rendered HTML (Read Only) view is pretty-printed.
The onAfterDeserialize event provides direct access to the actual model objects, after they are deserialized but before they are rendered on-screen. In this example code, the background of Block foo is rendered in red after the object is created:
Copyright TIBCO Software Inc. All Rights Reserved.
28
Note that the objJSX variable, which is an instance of jsx3.app.Model, points to the root object in the serialization file. For more examples, see Executing Code Before or After Deserialization.
29
30
4. Enter a value for the type in the Value field. If the value is JavaScript code, check the Eval checkbox. Values can be text or JavaScript code. For more information on entering JavaScript code, see Specifying Code in Dynamic Properties. For information on CSS values, see General Interface Component Guide. For example, you might want to add a custom color for the BG Color property. Enter a name for the property, such as bluebgcolor. Select jsxbgcolor as the type and enter a color value, such as #6E6CEF. You can use the Color Picker to choose a color. Choose Tools > Color Picker or click the Color Picker button in the Properties Editor palette. 5. Continue to edit values and do the following as needed to set up the list of properties: To add a new row, press Enter, click the Add button , or right-click a row and choose Insert New Record. To delete a row, select a row and click the Delete button . 6. Choose File > Save and Reload or right-click the work area tab and choose Save and Reload. 7. Browse to the jss folder of your project and enter a file name with the .xml extension. For dynamic properties files, be sure to use the .xml extension as some servers won't recognize the .jss extension used in previous releases. By default, General Interface, version 3.2 and higher, supports the .xml extension, which is the recommended file extension. 8. Click Save in the Save File dialog.
31
1. Set the dynamic properties file to automatically load with the application, so the new properties are always available. Right-click the dynamic properties file in the Project Files palette and choose Auto Load. 2. Return to the Live Component View and select the component you want to apply the property to in the Component Hierarchy palette or in the work area. 3. Find the property you added in the Properties Editor palette, such as BG Color, and right-click the Value cell to invoke the lookup list of property values. The property value you added displays on the list.
32
Component Libraries palette includes the following tabs: System tab: A tree that shows all of the built-in system components. These files are stored at the path GI_HOME/GI_Builder/prototypes. User tab: A tree that shows the components that the current user has created in their local GI workspace. Components downloaded from GeneralInterface.org are also saved here. These files are stored at the path GI_WORKSPACE/prototypes.
Online tab: List of the shared components that have been previously uploaded to GeneralInterface.org.
the folder name. To remove components, select the components and click the Delete
33
Using Filters
The following filter options are available by clicking the Filters Function Description icon.
34
Show all available components. Show the components that the Dojo Foundation is currently featuring. Show the user ratings along with the component name.
Downloads Show the number of times that the component has been downloaded. User Date Show the login name of the user who uploaded the component. Show the date that the component was uploaded.
Using Feeds
The following options are available by clicking the Feeds icon. To view these options, you must be subscribe to Live Bookmarks. If you are not subscribed, you are prompted to do so when you first choose a Feeds option on the Online tab. Function Top Rated Description Show the components with the highest user ratings.
Most Popular Show the components that have been downloaded most frequently Most Recent Show the components that were uploaded most recently
35
XML/XSL Merge Tool is used for testing the text, HTML, or XML output from a merge operation. You can view both the parsed output and its source. If parsing errors occur, error notification is provided. You can open multiple instances of this tool.
Character-level debugging that helps you identify the location of any XML parsing errors.
36
To open the XML Mapping Utility, choose Tools > XML Mapping Utility.
For more information on the XML Mapping Utility, see Communicating with Data Services and Communicating with a Web Service Tutorial.
Visual Bindings
The XML Mapping Utility provides a visual interface for mapping GUI components to data services. You can use drag-and-drop to create bindings for inbound and outbound SOAP messages and XML documents. XML elements can be bound to the values of GUI objects, nodes in XML documents, and JavaScript variables. All mapping information is stored in an XML file referenced in the project. If modifications are needed, you reopen this file in the XML Mapping Utility.
Testing
When mappings are complete, the interaction with the data service can be tested. You can preview the outbound message before it is sent, test the message against the live service, preview the response message, and enter a callback script to execute when the response is received.
37
Jabber Support
General Interface Builder includes a Jabber client, allowing you to participate in chats from within Builder. The client is implemented on top of the Dojo XMPP library. It works with Jabber servers that support the Jabber HTTP Bind protocol, such as OpenFire. An OpenFire server is available for use at http://chat.generalinterface.org. Sign in with your Dojo Foundation account credentials. The Jabber client in Builder feature supports the following actions: Adding and removing buddies Assigning nicknames to buddies One-to-one conversations Online/away/offline buddy statuses To configure your Jabber settings, open the IDE Settings window, as described in Customizing the IDE. When Jabber is configured, you can open the Chat palette from the Palettes menu.
38
Product Documentation
Product documentation is available online at http://www.generalinterface.org/docs/display/DOC/Learning+Center.
Context-sensitive Help
To access context-sensitive help in General Interface Builder, move focus to an area of the IDE, such as a dialog, editor, or palette, and press Alt+F1 or click the Help button . To implement context-sensitive help in your applications, see Implementing Context-Sensitive Help.
Spyglass Help
Documentation is also available in a spyglass in various areas of General Interface Builder. A spyglass contains descriptive text in HTML and can contain more information than a tooltip. To invoke a spyglass, hover the mouse over the following areas in the IDE: Property names in the Properties Editor palette Model event names in the Events Editor palette APIs icon in the Settings panel of the XML Mapping Utility
You can also add spyglass documentation to your own applications using the Spyglass event (jsxspy) and the spy methods in the jsx3.gui.Interactive interface. For more information, see General Interface API Reference.
API Documentation
Online API documentation is available online at http://www.generalinterface.org/docs/display/DOC/API+Documentation.
39
40
General Interface Classes Classes automatically loaded by General Interface. See the next table.
Application Classes
Application Code
Dynamically Load other General Interface classes using loaded jsx3.require() or automatically with deserialization.
Auto Load disabled. Add Auto Load disabled. custom classes to class path. Load code using Load class using Server.loadResource(). jsx3.require() or automatically with deserialization.
jsx3.app.AddIn jsx3.app.Model jsx3.app.Server jsx3.gui.Alerts jsx3.gui.Heavyweight jsx3.gui.Painted jsx3.lang.Method jsx3.lang.Package jsx3.net.URIResolver jsx3.util.List
jsx3.app.Cache jsx3.app.Properties jsx3.app.Settings jsx3.gui.Block jsx3.gui.HotKey jsx3.lang.Class jsx3.lang.NativeError jsx3.net.Request jsx3.util.DateFormat jsx3.util.Locale
jsx3.app.DOM jsx3.app.PropsBundle jsx3.gui.Alerts jsx3.gui.Event jsx3.gui.Interactive jsx3.lang.Exception jsx3.lang.Object jsx3.net.URI jsx3.util.EventDispatcher jsx3.util.Logger
Application Classes
To statically load your application class files as the application loads, enable the Auto Load option for the JavaScript files in the Project Files palette. For more information, see Enabling the Auto Load Option. To dynamically load custom application classes when the Auto Load option is off, classes must meet the following requirements:
Copyright TIBCO Software Inc. All Rights Reserved.
41
meet the following requirements: The classes must be on the class path, so the system class loader can find the classes. See Specifying Class Paths. The jsx3.require() method must be used to load classes explicitly that are not loaded automatically by the component through deserialization. See jsx3.require() Method.
Application Code
To statically load your application code as the application initializes, enable Auto Load for the JavaScript files in the Project Files palette. For more information, see Enabling the Auto Load Option. If you don't want the application code statically loaded, you can load it dynamically using the Server.loadResource() method. This method looks up a resource registered with the application by its id. The resource must be registered in the config.xml file of the application. For more information, see General Interface API Reference.
When you enable the Auto Load option, the onLoad attribute for the JavaScript file is set to true in the application configuration file (config.xml).
42
<record jsxid="1" type="map"> <record jsxid="id" type="string">main_js</record> <record jsxid="type" type="string">script</record> <record jsxid="onLoad" type="boolean">true</record> <record jsxid="src" type="string">js/logic.js</record> </record>
jsx3.require() Method
The jsx3.require() method can be used to load classes explicitly. Use the fully qualified class name when using the jsx3.require() method. For example,
jsx3.require("jsx3.net.Form");
Only classes that can be found by the system class loader are loaded. Custom classes can be added on the Classpath panel of the Project Settings dialog. See Specifying Class Paths. When a component file is deserialized, the class of each object encountered in the file is dynamically loaded if it's not already loaded. Therefore, it's often not necessary to use the jsx3.require() method with classes that descend from jsx3.app.Model. However, if JavaScript code references these classes and if the code executes before a deserialization automatically loads the class, you must use the jsx3.require() method to explicitly load the class. The jsx3.require() method must be called at least once before making these types of references: A static reference to a class descending from jsx3.gui.Model (typically jsx3.gui.**). Any references to subclasses of Model that execute before the class is loaded through object deserialization.
43
URI Resolution
This section describes how URIs are resolved in General Interface. A Uniform Resource Identifier (URI) identifies or names a resource required by the application. The URI functionality of General Interface has been updated to provide additional functionality and to simplify development. Project resources are now referenced by the project configuration file (config.xml) relative to the base directory of the project. Referencing resources in the configuration file allows you to rename and move project directories more easily. Any relative URI that isn't of a legacy 3.1 format (beginning with JSX/ or JSXAPPS/) is resolved relative to a base URI that depends on the context of the URI. General Interface 3.1 applications perform as expected in version 3.2 and higher. However, it is strongly recommended that you update your applications to take advantage of the relative URI functionality.
44
The version 3.1 format is still valid in version 3.2 and higher, because URIs beginning with JSXAPPS/ are handled in a special manner. As of version 3.2, these URIs can be written relative to the base directory of the project. The previous example can now be written as follows to take advantage of relative paths:
subfolders/filename.xml
In General Interface Builder, version 3.2 and higher, any property editable in the Properties Editor palette can accept a relative URI, which is resolved relative to the project directory. For example, these properties accept relative URIs: the Image property for ToolbarButton and the XML URL property for List. URIs that appear in free form properties, such as Text/HTML for Block, are never resolved. URIs set as values of attributes in the Attributes Editor are also not resolved. In summary, the URI requirements in General Interface Builder, version 3.2 and higher, include the following: 1. All properties editable in the Properties Editor palette that expect a path (XML URL, Image URL, and so on) can take an absolute path or a path relative to the project directory. 2. All other inputs (HTML attributes, free-form HTML) have to be pre- resolved statically or using the URIResolver API. See URI Resolvers. Using dynamic properties is one way of externalizing these paths. Be certain that values stored in the dynamic property agree with the requirements described above, depending on how they are used. To reference a resource that is located outside of the project directory, use a relative URI starting with one or more "../" tokens or one of the supported absolute URI formats. See URI Format Support.
45
URI Format
JSX/...
Description Legacy format for General Interface 3.1. Resolves relative to the parent of the JSX directory as determined by the location of the JSX30.js script. If multiple script elements are used in one HTML page, the URL for the JSX30.js script file must be the same. Legacy format for General Interface 3.1. Resolves relative to the parent of the JSXAPPS directory, as determined by the jsxapppath query parameter of the src attribute of the script element referencing the JSX30.js script. If multiple script elements are used in one HTML page, the applications must be located in the same JSXAPPS directory. Legacy format for General Interface 3.1. Resolves as JSX/... when General Interface Builder is running. Applications should not reference any URIs of this format, because the GI_Builder directory can't be deployed under the standard licensing terms. Format for General Interface 3.2 and higher. Resolves relative to the JSX directory as determined by the location of the JSX30.js script.
JSXAPPS/...
GI_Builder/...
jsx:///...
jsxaddin://addin/... Format for General Interface 3.2 and higher. Resolves relative to the base directory of the add-in specified by the host portion (addin) of
the URI. The host portion of the URI follows the double forward slashes (//). The host of the URI should be the add-in key ( AddIn.getKey()) with any colon characters (:) replaced with an exclamation point (!). The add-in must be loaded for the URI to resolve correctly.
jsxuser:///...
Format for General Interface 3.2 and higher. Resolves relative to the parent of the JSXAPPS directory (workspace). When General Interface Builder is running, this URI resolves relative to the workspace directory. General Interface 3.2 and higher format. If the Server instance corresponding to the host portion of the URI is loaded into memory, the URI is resolved relative to the application base directory ( jsxappbase). The host portion (app) of the URI is the relative path from the JSXAPPS directory to the application base directory containing the config.xml file with any forward slashes (\/) replaced with exclamation points (!). If the Server instance isn't loaded into memory, the URI resolves relative to the directory containing the config.xml of the application. Note: You can override the application base directory (jsxappbase). See Overriding the Application Base Directory.
jsxapp://app/...
Additionally, any URIs specifying a scheme or an absolute path (beginning with a forward slash) are also considered absolute and will not be modified. Any other URI is considered relative and will be resolved by a URI resolver depending on the context in which it is encountered.
46
URI Resolvers
General Interface, version 3.2, introduces a new interface, jsx3.net.URIResolver. An object that uses relative URIs must implement methods in the URIResolver interface to define a context against which those URIs are resolved. Two classes, jsx3.app.Server and jsx3.app.AddIn, implement this interface. The Server class uses the jsxapp: URI scheme and the AddIn class uses the jsxaddin: URI scheme described previously. Additionally, static resolvers are provided for the jsx: and jsxuser: schemes. For more information, see General Interface API Reference.
47
Menu Tree Select and Combo Matrix Charting There are two ways to work with CDF documents: Through a CDF component, such as Matrix and Tree Directly with the API. See the jsx3.xml.CDF.Document class in the online API help in General Interface Builder.
CDF Schema
The CDF schema is described by the following XSD:
48
<?xml version="1.0"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <xsd:element name="data"> <xsd:complexType> <xsd:sequence> <xsd:element type="cdfrecord" name="record" maxOccurs="unbounded" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="jsxid"> <xsd:simpleType> <xsd:restriction base="xsd:string"> <xsd:enumeration value="jsxroot"/> </xsd:restriction> </xsd:simpleType> </xsd:attribute> </xsd:complexType> </xsd:element> <xsd:complexType name="cdfrecord"> <xsd:sequence> <xsd:element type="cdfrecord" name="record" maxOccurs="unbounded" minOccurs="0"/> </xsd:sequence> <xsd:attribute name="jsxtip" type="xsd:string"/> <xsd:attribute name="jsxvalue" type="xsd:string"/> <xsd:attribute name="jsxdivider" type="xsd:string"/> <xsd:attribute name="jsxtext" type="xsd:string"/> <xsd:attribute name="jsxstyle" type="xsd:string"/> <xsd:attribute name="jsxkeycode" type="xsd:string"/> <xsd:attribute name="jsxunselectable" type="xsd:string"/> <xsd:attribute name="jsxexecute" type="xsd:string"/> <xsd:attribute name="jsxgroupname" type="xsd:string"/> <xsd:attribute name="jsximg" type="xsd:string"/> <xsd:attribute name="jsxselected" type="xsd:string"/> <xsd:attribute name="jsxid" use="required" type="xsd:string"/> </xsd:complexType> </xsd:schema>
The CDF schema is an open schema that can be extended using custom entities and attributes. In the following example, the jsxtext and jsxid attributes are system attributes with special meaning. The jsxid attribute is required for a record in the CDF. This attribute acts as a key and should be a unique value. The number and name attributes are custom, developer-defined attributes.
49
<?xml version="1.0"?> <data name="" number="" jsxid="jsxroot"> <record name="a" number="0" jsxid="null" jsxtext="Select a State"/> <record name="b" number="1" jsxid="AL" jsxtext="ALABAMA"/> <record name="c" number="2" jsxid="AK" jsxtext="ALASKA"/> <record name="d" number="3" jsxid="AZ" jsxtext="ARIZONA"/> <record name="e" number="4" jsxid="AR" jsxtext="ARKANSAS"/> <record name="f" number="5" jsxid="CA" jsxtext="CALIFORNIA"/> <record name="g" number="6" jsxid="CO" jsxtext="COLORADO"/> <record name="h" number="7" jsxid="CT" jsxtext="CONNECTICUT"/> <record name="i" number="8" jsxid="DE" jsxtext="DELAWARE"/> ... <record name="Y" number="50" jsxid="WI" jsxtext="WISCONSIN"/> <record name="Z" number="51" jsxid="WY" jsxtext="WYOMING"/> </data>
50
<data jsxid="jsxroot"> <record jsxid="1" jsxtext="New"/> <record jsxid="2" jsxtext="Open"/> <record jsxid="3" jsxtext="Save"/> </data>
<data jsxid="jsxroot"> <record jsxid="1" jsxtext="New"/> <record jsxid="2" jsxtext="Open"> <record jsxid="2a" jsxtext="Image..."/> <record jsxid="2b" jsxtext="Document..." /> </record> <record jsxid="3" jsxtext="Save"/> </data>
<data jsxid="jsxroot"> <record jsxid="2" jsxtext="Font"> <record jsxid="2a" jsxtext="Bold" jsxgroupname= "font" jsxselected="1" /> <record jsxid="2b" jsxtext="Underline" jsxgroupname= "font"/> <record jsxid="2c" jsxtext="Italic" jsxgroupname= "font"/> </record> <record jsxid="3" jsxtext="Color"/> </data>
51
<data jsxid="jsxroot"> <record jsxid="1a" jsxtext="Bold"/> <record jsxid="1b" jsxtext="Underline" jsxdivider="1"/> <record jsxid="1c" jsxtext="Italic" jsximg="x.gif"/> <lookups jsxid="2"> <record jsxid="3" jsxtext="IL"/> <record jsxid="4" jsxtext="MA"/> <record jsxid="5" jsxtext="NV"/> <record jsxid="6" jsxtext="WI"/> </lookups> </data>
52
Attribute
jsxdisabled
Component
Description
Button, Checkbox, Disables the record so that a user cannot select it. ImageButton, Menu, The record text is displayed in a grey color. Specify a RadioButton, value of 1 to disable the record. ToolbarButton Menu Creates a linear divider between the current record and the preceding record. Specify a value of 1 to display the divider. Allows an event to run a program function when the event fires. A function name or a string of JavaScript statements can be specified. Separate multiple statements with a semicolon (;) character. For example, jsxexecute="var a=12;var b='5';" Adds the record to a group that can be used by multiple CDF records or components. Records in a group are mutually exclusive options. For example, a menu for selecting fonts allows only one font option to be chosen. Uniquely identifies the CDF record. This value can be user-defined or automatically generated using the getKey() method (jsx3.xml.CDF). This attribute is required. References a graphic file to use as an icon. Specify the file path relative to the project directory, for example, images/icon.gif. Image position depends on the component. For best results, use a 16x16 transparent GIF file. Defines a keyboard shortcut for calling the record. Specify any named key, such as Tab, Alt, Shift, or Ctrl, and use the plus character (+) as a delimiter. For example, jsxkeycode="ctrl+e". Disables a visible mask (checkbox, radio button, menu, and so on) so it's hidden and a user can't select it. Specify a value of 1 to hide the mask for that row.
jsxdivider
jsxexecute
jsxgroupname
Matrix, Menu
jsxid
all
jsximg
jsxkeycode
Menu
jsxnomask
Button, Checkbox, ImageButton, Menu, RadioButton, ToolbarButton (when used as a Matrix mask) Matrix, Menu, Tree, Table Matrix, Menu, Tree, Select, Table
jsxselected
Specifies whether the record is selected or not selected by default. Specify a value of 1 to define the record as selected. Applies a CSS style to this record. Specify any CSS code. For example, jsxstyle="font-weight:bold;".
jsxstyle
53
jsxtext
Defines the visible text for the record. For example, in a menu component, the value of this attribute is the name of the menu item as displayed in the application. Defines the tooltip text to display when the cursor hovers over the record. For example, jsxtip="Type your address here". Specifies whether a tree node or list item can be selected by end users. Specify a value of 1 to prevent the record from being selected. When the value of this attribute is 1, the execute method for the record cannot be called.
jsxtip
Any CDF attribute value of jsxtext, jsxtip, jsximg, jsxkeyode, jsxstyle, or jsxclass in the form of {xxx} is replaced with the dynamic property xxxif it exists. If the property doesn't exist, then the value isn't changed. Dynamic properties come from the server owning the CDF control. The conversion occurs when the XML document is retrieved from source and before it's placed in the cache. For more information, see the API for CDF.convertProperties().
CDF records can also include custom attributes. Custom attribute names can be any string except names of system attributes. To add attributes to a CDF record, call the insertRecordProperty() method. You can also manually edit the CDF document on the file system, or open the cached file in General Interface Builder.
54
This is a good choice if a CDF component isn't required. For example, the Properties Editor palette in General Interface Builder uses the API to create the CDF on the fly at runtime and generate the list of available properties for the selected component in the work area. For method details for the jsx3.xml.CDF.Document class, see the online API help in General Interface Builder.
For method details, see the online API help in General Interface Builder.
55
To avoid working with the system-defined name, use the XML Cache ID property to specify a name for the CDF document or access the CDF document through the object. From an object, by calling the getXML() method (jsx3.xml.Cacheable). All CDF components implement the jsx3.xml.Cacheable interface, which provides this method. For example,
var objXML = myCdfControl.getXML();
If you've instantiated a CDF directly and aren't using a CDF component, you don't need to get a handle to the CDF document.
Accessing a Node
You can access a record node within a CDF document in one of the following ways: By calling the selectSingleNode() method (jsx3.xml.Entity) for the CDF document and passing the appropriate XSL query. The following code example returns the node with element name record and jsxid value of 12.
myCdfDocument.selectSingleNode(//record\[@jsxid='12']);
* From an object that implements the CDF interface, by calling the getRecordNode() method (jsx3.xml.CDF). For example,
myObject.getRecordNode(12);
56
57
Method
getKey
Summary Generates a unique identifier for use as the jsxidattribute for a CDF record. This value persists only for the length of the browser session. Unique values that persist across browser sessions must be generated by the developer. A factory method for creating a new CDF document containing the following XML: <data jsxid="jsxroot"/> Transfers a CDF record between components. The record must have a unique jsxidvalue to be transferred. If no CDF document exists for the adopting parent, a document is created and added to the cache. If successful, this method returns a jsx3.xml.Entity instance, which is an object handle to the transferred record. The view for the record is automatically updated. Equivalent to adoptRecord, except that the to-be relationship is as a previousSibling to the CDF record identified by the parameter, strSiblingRecordId. Deletes a CDF record from the component CDF document. If successful, this method returns a jsx3.xml.Entity instance, which is an object handle to the deleted record node. Updating the view for the record is optional.
newDocument
adoptRecord
adoptRecordBefore
deleteRecord
deleteRecordProperty Deletes a specific property from a CDF record. The record must have a unique jsxid value. Do not call this method to delete the jsxid
property.
getRecord
Returns a JavaScript object that is a clone of the specified CDF record. Any updates to this clone doesn't affect the original record unless you call object.insertRecord() and pass the modified clone as the input parameter. Returns a jsx3.xml.Entity instance representing the actual object handle to the CDF record. Updating this object also directly updates the model. To synchronize the view after an update, call the following:
object.redrawRecord(strRecordId,jsx3.xml.CDF.UPDATE);
getRecordNode
insertRecord
Inserts a new record into the CDF document for the component. If no CDF document exists for the component, a document is created and added to the cache. If a record with the same jsxid value already exists, the existing record is updated. Creates a new CDF record and inserts it into the CDF data source of this object, before the record identified by the parameter, strSiblingRecordId. Inserts a new record node into the control's XML-formatted data source. If no CDF document exists for the component, a document is created and added to the cache. If a record with the same jsxid value already exists, the existing record is updated. This function is for inserting records as XML node entities rather than JavaScript objects.
insertRecordBefore
insertRecordNode
58
insertRecordProperty Inserts a new CDF attribute and corresponding value for the specified
CDF record. The attribute can be one of the system attributes defined in CDF System Attributes or a custom attribute. Updating the view for the record is optional.
Adding Records
Use the insertRecord() and insertRecordNode() methods to add records to a CDF document. The two methods are functionally equivalent, but insertRecord() takes a JavaScript object as input, while insertRecordNode() takes an XML entity. With insertRecord(), you specify the jsxid attribute, along with any other CDF attributes for the record, as properties of the object.
insertRecord Example
The following sample JavaScript code illustrates how to add records to a Matrix component using insertRecord() :
// get a handle to the matrix var objMatrix = myServer.getJSXByName("myMatrix"); // new CDF record var objRecord = new Object(); objRecord.jsxid = jsx3.CDF.getKey(); objRecord.Date = myServer.getJSXByName("dateEntry").getValue(); objRecord.Security = myServer.getJSXByName("securityEntry").getValue(); objRecord.Open = myServer.getJSXByName("openEntry").getValue(); objRecord.High = myServer.getJSXByName("highEntry").getValue(); // insert the record and pass true so it is redrawn without repaint objMatrix.insertRecord(objRecord, null, true);
In this example, the new CDF record object is objRecord. The first property defined for this object, jsxid, is a required system attribute that must be unique. The getKey() method is used to generate a unique jsxid value for this record. Other properties, Date, Security, Open, and High, become custom attributes of the CDF record. Values for these properties are provided by components in the application. In addition to a JavaScript object, the insertRecord() call takes two parameters the numeric identifier (jsxidvalue of a parent object) and an optional Boolean parameter for a redraw operation. When null is specified for the second parameter, as in this example, the record is added to the root element of the CDF document. Since this example adds a single record, the overhead associated with redrawing the record is insignificant. When adding multiple records, such as in a loop, consider passing a value of false for this parameter and repainting the entire component after all records are added. For details, see Redrawing and Repainting Records.
59
Updating Records
When you add a record that has the same jsxid value as an existing record in the CDF document, the existing record is replaced. Make sure jsxid values are unique before adding records. For details, see Generating Unique Identifiers. You can use the insertRecordProperty() method to add attributes to an existing record in a CDF document. Specify the jsxidvalue of the record to modify, along with the attribute name and attribute value. The following sample illustrates how to add an attribute to an existing record within an ID (jsxid) of 58:
objList.insertRecordProperty("58","mypropname","mypropvalue");
The process of removing attributes is similar. Using deleteRecordProperty(), specify the jsxid value of the record to modify and the name of the attribute to remove. Although not specifically restricted by the API, do not remove the jsxid attribute from a record. The following sample JavaScript code illustrates how to remove an attribute from an existing record:
objList.deleteRecordProperty("11","jsximg");
In both of the preceding examples, the record is automatically refreshed to reflect the change in the application. You could also pass a value of false for the optional bRedraw parameter to prevent the redraw operation. For details on optimizing redraw and repaint operations, see Redrawing and Repainting Records.
Deleting Records
Use the deleteRecord() method to delete a record from a CDF document. This method returns an object handle to the XML entity instance that was removed. The following sample JavaScript code illustrates how to delete an existing record:
var objMatrix = myServer.getJSXByName("myMatrix"); objMatrix.deleteRecord(strRecordId);
60
In general, repainting the component affects all records and is resource-intensive. Repainting the component should be avoided unless a sizable number of records are modified. For example, if many records are added in an iterative manner, it can be more efficient to repaint the component once, after all additions have been made. To repaint a component, call the repaint() method for the specific component. CDF methods, with the exception of the adoptRecord()}}method, accept an optional Boolean
parameter that signifies whether the on-screen view should be immediately updated to reflect the update to the in-memory model. A value of {{true , which is the default value, redraws the record after modification. For the adoptRecord() method, both controls (the former
Counting Records
You can count the number of records in a CDF document by querying for all records and calling the getLength() method on the object that is returned. The following sample illustrates this for the List control.
var objXML = myList.getXML(); var objNodes = objXML.selectNodes("//record"); alert("The number of records is: " + objNodes.size());
First, call the getXML() method for the object, then the selectNodes() method (jsx3.xml.Entity) for the XML entity, passing the path for the nodes to select. This method returns a handle to the jsx3.util.List object containing all record nodes in the CDF document. Calling the getLength() method on this object returns the number of CDF records.
The flexible CDF schema feature allows these same classes to consume datasources that do not strictly follow CDF. This feature is particularly useful for consuming pre-existing XML datasources that were created without knowledge of CDF. With the flexible CDF schema feature, The core CDF schema elements and attributes data, record and jsxid can be renamed to anything A single data source can drive multiple CDF controls, each with its own view of the data
61
An alternative way of converting data sources to CDF is to use XSL Transformers. XSL Transformers allow you to define one or more XSL transformations to convert the source data to CDF before it is stored in the XML application cache and is used to render a CDF control. Whereas the flexible CDF schema feature supports only XML schemas that have a similar structure to CDF, the XSL transformers approach supports any arbitrary XML schema. Knowledge of XSL is required to use this approach. See the API documentation for jsx3.xml.Cacheable for more information on XML Transformers.
This additional level of indirection (this.getSchema().getProp("text") instead of "jsxtext") allows the CDFSchema object to control how each CDF control views its datasource. The default CDFSchema object returns "jsxtext" from a call to getProp("text"). However, you can modify the schema so that it returns "label" instead. This change would allow you to have a CDF datasource such as
<data jsxid="jsxroot"> <record jsxid="1" label="One"/> ... </data>
62
Using the same datasource for two different controls is simply a matter of defining a unique CDF schema for each control. Click to download a sample project that uses the flexible CDF schema feature: GI-702.zip.
63
64
p:\padding="8"> <Select p:name="sel1" id:xml="HRTL129Q"> <id:\data href="HRTL129Q"> <![CDATA[ <data jsxid="jsxroot"> <record jsxid="TIBX" jsxtext="TIBCO"/> <record jsxid="MSFT" jsxtext="Microsoft"/> <record jsxid="YHOO" jsxtext="Yahoo!"/> <record jsxid="EBAY" jsxtext="Ebay"/> <record jsxid="GOOG" jsxtext="Google"/> <record jsxid="IBM" jsxtext="IBM"/> </data> ]]> </id:\data> </Select> </Block> </Splitter>
65
</Dialog> </component>
66
CIF Definitions
Node Name component Namespace Description
http://xsd.tns.tibco.com/gi/cif/2006 Root level node. Supports child elements belon the same namespace. Any child element (exclu those named meta, which is a reserved name) is understood to be an instance of jsx3.app.Model deserialized as part of the standard General Int DOM. In other words, any object hierarchy communicated by the XML serialization forma be a true reflection of the General Interface DO the XML is deserialized.
@classpath
http://xsd.tns.tibco.com/gi/cif/2006 This attribute can belong to any node belongin http://xsd.tns.tibco.com/gi/cif/2006 namespace for meta nodes. If bound to the root node, compo this is the default class path for all GUI control defined in the serialization file. Any GUI contro implements this attribute can override the root setting.
meta
Immediate child of the root node, component. Describes meta-related information about the component, including the following name, i
description, onAfterDeserailze, onBeforeDeserailize.
@name
Attribute of the meta node. Defines the name of meta attribute. For example, onAfterDeserializ
data
http://xsd.tns.tibco.com/gi/cif/2006 Inline data node. Allows for the serialization of according to an open format. The default implementation of this node assumes that it co CDATA content. However, this node could pro handler-for attribute as a means for serializing deserialization custom data types.
@href
Provides the unique ID for the inline data node among all inline data nodes in the document.
@handler-for
Provides the name of the JavaScript object that handles the deserialization of either the compo the data. Applies only to the data node that bel the namespace, http://xsd.tns.tibco.com/gi/cif/2006/inlinedata.
67
In order to ensure proper compatibility with the existing serialization format and provide for good runtime deserialization performance, XML namespaces are used to uniquely identify how to deserialize a given property on a standard General Interface object definition. The use of namespaces allows the deserialized to quickly categorize the obj properties. This prevents the need for expensive runtime lookups and the possibility of namespace collisions. For example, the drag property on a List definition may belong to the property namespace ( [http://xsd.tns.tibco.com/gi/cif/2006/property]), specifying whether or not the given List supports drag-and-drop. It could also belong to the event namespace ([http://xsd.tns.tibco.com/gi/cif/2006/events]) and relate to the handler code to fire when a drag event fires on the List. It could also be a user-defined property ([http://xsd.tns.tibco.com/gi/cif/2006] /userdefined or [http://xsd.tns.tibco.com/gi/cif/2006/userdefined.eva The drag property could also be a dynamic propert
68
Once parsed by the XML Mapping Utility, XML documents are persisted in CXF format. A CXF rules document can then be mapped to application objects, such as CDF documents, text boxes, and nodes in the Local Data Cache palette. Regardless of whether WSDL, Schema, or XML is used, all input formats result in the same transactional format. In practice, this means that the interactions with a SOAP service can be defined by using WSDL or a sample SOAP message, such as an Envelope, as a starting point. Ultimately, the source type (WSDL, Schema, or XML) used to create a CXF rules document is irrelevant once the CXF document has been created, as all formats are persisted using CXF. Another way to think about CXF is to think of it as an interpretive language that is able to interface between the XML document formats used by a given web service and the native CDF and JavaScript formats used by General Interface. Just as it is important to be versed in CDF in order to know how data is used within General Interface, an understanding of CXF provides insight into how data is shared between General Interface and data services. While CDF provides the format for data while it is within the control of General Interface, CXF provides the bridge to convert this information to the format required by the given web service.
69
<data jsxid="jsxroot" jsxnamespace="jsx3.xml.Mapper" jsxversion="1.0"> <record jsxid="13" jsxtext="WSDL (/GoogleSearch.wsdl)" src="http://api.google.com/GoogleSearch.wsdl" type="W" path=""> <record jsxid="12" jsxtext="Service" path="/" type="S" soapstyle="rpc"> <record jsxid="74321" jsxtext="doGoogleSearch" opname="doGoogleSearch" endpoint="beta2" type="P" path="/"> <headers jsxid="7"> <record jsxid="3" name="SOAPAction" value="urn:GoogleSearchAction"/> <record jsxid="4" name="Content-Type" value="text/xml"/> </headers> <record jsxid="5" jsxtext="Input (request)" type="I" stubsrc="soap.xml" stubpath="/" onbeforesend="some code" soapuse="encoded" soaprpcns="urn:GoogleSearch" soapencstyle="http://schemas.xmlsoap.org/soap/encoding/"> <record jsxtext="doGoogleSearch" jsxid="41037" type="C" tns="urn:GoogleSearch" path="/"> <record jsxtext="key" jsxid="1" type="E" datatype="xsd:string" simple="1" path="/" repeat="false"> <mappings jsxid="11"> <record jsxid="10" name="Script" value="setValue(true);"/> </mappings> </record> </record> </record> <record jsxid="9" jsxtext="Output (response)" type="O" soapuse="encoded" soaprpcns="urn:GoogleSearch" soapencstyle="http://schemas.xmlsoap.org/soap/encoding/" stubsrc="/" onafterreceive="some code"> <record jsxtext="doGoogleSearchResponse" jsxid="20020" type="C" tns="urn:GoogleSearch" path="/message[5]"> <record jsxid="8" jsxtext="return" type="C" path="/" datatype="typens:GoogleSearchResult"> <record jsxid="5" jsxtext="documentFiltering" type="E" path="/" datatype="xsd:boolean" simple="1" jsxselected="1"> <restrictions jsxid="16"> <record jsxid="14" name="enumeration" value="true"/> <record jsxid="15" name="enumeration" value="false"/> </restrictions> </record> </record> </record> </record> </record> </record> </record> </data>
70
71
Attribute
datatype
Description Data type for the node. For example, xsd:string. This is relevant to RPC Encoded WSDL inputs. When the final message is generated and sent to the remote service, this value is used to specify the encoding for a node in the message. URL for the remote service to contact. Although WSDL binds the endpoint to the service (which can encapsulate one or more operations), CXF binds the endpoint to each individual operation. If equal to 1, the node is flagged as structural, which means that it isn't part of the generated message. The node appears in the rules tree as an organizing element but isn't generated and sent with the request, essentially removing the abstract node and appending its descendant structures to the structural node's immediate parent. System ID for the record. This is assigned by the system and is unique for each node in the CXF document. This attribute is only relevant at design time. System text for the record. More importantly, this is the node name (for attributes and entities) in the message. The HTTP transport method: GET, POST, PUT, DELETE. Applies to records in the CXF that define mappings, HTTP headers, and restrictions. In the case of mappings, this is the map type (i.e., DOM, Script, CDF Document, and so on). For HTTP headers, this is the header name. For restrictions, this is the type of the restriction (enumeration, nillable, pattern, and so on). message.
endpoint
groupref
jsxid
jsxtext
method name
onbeforesend opname
JavaScript code to execute immediately before sending the request message. The name of the operation. This value is unique among all other operation nodes in the CXF document. In the case of a CXF that was created without a WSDL, there is only one operation for the CXF named jsxtransaction. The node path to find this item in the original source Schema used to create the CXF. This attribute is only used by WSDL and Schema input types and is only relevant at design time. If equal to 1, this node will be flagged by the XML Mapping Utility as a referential node, pointing to a group or attributeGroupelement in the source WSDL/Schema. This attribute is only relevant at design time and is used to convert the indirection used by Schema to the concrete structures used by CXF. If this attribute exists, its value will be evaluated as JavaScript within the context of the jsx3.net.Service instance that is processing the given CXF. If the result evaluates to true, the given branch in the CXF will be processed again. This only applies to XML documents generated on the client. This value is ignored when processing a service response.
path
ref
repeat
72
simple
If equal to 1, the data type for this node is one of the simple types defined by Schema (http://www.w3.org/2001/XMLSchema-instance). If equal to http://schemas.xmlsoap.org/soap/encoding/, the operation is designated as encoded, meaning each node will be tagged with its data type. This applies only to WSDL input types that use RPC encoding. If an RPC Encoded message, the namespace for the remote procedure (the message). The SOAP style document or rpc. The SOAP use encoded or literal. URL for the source document that is serving as the pattern master for generating the CXF. The pattern master is the input document that was used by the XML Mapping Utility to create the CXF (typically a WSDL). This attribute is only relevant at design time. URL for the base shell document. Also used for inbound messages (response nodes) when running in static mode. The XSL Query for the node in the base shell document ( stubsrc) to which the generated document will be appended. If this value exists on a Rule node contained by an Input node, the Rule will be qualified and the value of the tnswill be appended to the root node in the response document. If it exists on a rule contained by the output or fault nodes, it defines a qualified namespace, meaning that it isn't enough for the node names to match for the rule to be applied; rather, the node's namespace must also match. Represents the target namespace for the data type and applies to rpc-encoded messages. For example, if the target namespace tns is abc.com and ttns is def.com, you would see something similar to the following in a message:
<jsx1:myNode xsi:type="jsx2:myType" xmlns:jsx1="abc" xmlns:jsx2="def" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
soapencstyle
soaprpcns
stubsrc
stubpath
tns
ttns
type
The type of rule. For example, A, C, E, and so on. The most common type is E, which represents a mapping rule to an Entity node type in the CXF. Applies to records in the CXF that define mappings, HTTP headers, and restrictions. In the case of mappings, this is the map path/value. For HTTP headers, this is the header value. For restrictions, this is the value of the restriction.
value
73
Attribute
Description
jsxid, jsxtext, This is the top-level node in a CXF document that type, src, type resulted from a WSDL input. The most relevant attribute is src, which describes the location of
the original WSDL in case the CXF document is in-edit and still needs a back-reference to the original WSDL.
Service //record[@type='S'] jsxid, jsxtext, This is a second-level node in a CXF document that resulted from a WSDL input. It is an type, path, immediate child of the WSDL-type node. It soapstyle
describes a service to which one or more operations belong. Although the service does define an endpoint in the original WSDL, this information is saved to the Operation nodes for improved flexibility.
Operation //record[@type='O'] jsxid, jsxtext, type, endpoint, method, opname, path
This is a third-level node in a CXF document that resulted from a WSDL input. It is an immediate child of the Service node. The operation describes the type of messages involved, including input, output, and fault.
Transaction //record[@type='T']
jsxid, jsxtext, This is the top-level node in a CXF that resulted type, endpoint, from a non-WSDL input. It is equivalent to the method, opname third-level Operation node that results from a
WSDL input, except that it does not define a path. Instead, its child input and output rules define the path to their respective source documents.
Input //record[@type='I'] jsxid, jsxtext, type, onbeforesend, path, soapencstyle, soaprpcns, soapuse, src, stubpath, stubsrc jsxid, jsxtext, type, onafterreceive, path, soapencstyle, soaprpcns, soapuse, src, stubsrc
This node is the child of either an Operation or Transaction node. It contains the rules necessary to create the input (the document that will be sent as part of the request). When the immediate parent is a Transaction node, the input will define a src attribute, if relevant.
Output //record[@type='O']
This node is the child of either an Operation or Transaction node. It contains the rules necessary to create the output (the response that will be processed). When the immediate parent is a Transaction node, the output will define a src attribute, if relevant.
74
Fault //record[@type='F']
This node is a child of an Operation node. It defines an alternative ruleset for processing a fault document returned from the Service. It is executed only when the service responds with a non-202, 200, or -0 HTTP status code. It does not support the extra attributes that the Output node supports. Rule nodes define the mappings and restrictions and are used to either generate a node in the input message or process a node in the output. Note the following definitions: A: attribute node E: entity node D: CDATA node C: complex node (contains E, C, D, or A nodes) Mapping nodes are bound to an entity called mappings, which, in turn, is bound to a given Rule node. There can be zero or more mappings for a given rule. Restriction nodes are bound to an entity called restrictions, which, in turn, is bound to a given Rule node. There can be zero or more restrictions for a given rule. The restrictions can be used to validate mapped input. Header nodes are bound to an entity called headers, which, in turn, is bound to a given Operation or Transaction node. There can be zero or more HTTP headers for a given operation.
Mapping //mappings/record
Header //headers/record
75
Sending Data
You can send data from an application using the methods: GET or POST. Depending upon the capabilities of the server being called, other methods like DELETE, PUT, and HEAD may also be called. The following describes the general pattern for sending data: 1. Create a new jsx3.net.Request instance. 2. Call the open() method and specify the interaction type (GET, POST, and so on). 3. Call the send() method. For a POST interaction, pass the string content as the only parameter to the send() method. For GET, use another content mechanism, such as an overloaded URL, as in this example:
76
//create response callback and subscribe function onResponse(objEvent) { var req = objEvent.target; alert(req.getResponseText()); }; req.subscribe(jsx3.net.Request.EVENT_ON_RESPONSE,onResponse);
//send req.send();
General Interface applications perform best when they use asynchronous data access. However, there are times when you might want to synchronously access data. The above call made synchronously is shown in the following example:
//initialize and open var req = jsx3.net.Request.open("GET","http://www.tibco.com?myQuery=1", false);
Receiving Data
The process for receiving data depends on whether the data is valid XML or another format.
77
To save the response document for repeated access, use the setDocument function to load it into the local data cache as follows:
myApp.getCache().setDocument("MyCacheDocument", repXML);
Also note that the Request class has different methods for accessing data. The example shown above is the simplest of all data calls: a synchronous HTTP GET. In fact, requesting and caching data in this manner can be done with only one API call, openDocument as shown in the following example:
var repXML = someApp.getCache().openDocument(someURL,someCacheId);
The Cache class has different methods for accessing data more efficiently than the {{openDocument}} method just described. For example, the method {{getOrOpenDocument}} will first check the cache for the document before attempting to load it.
If the document is large or the server will respond with a known latency, fetch the document asynchronously, using {{getOrOpenAsync}}. This method returns the corresponding document synchronously if it already exists in the cache. If the document does not exist in the cache, then it is loaded asynchronously and the method returns a placeholder document. The namespace URI of this placeholder document is {{jsx3.xml.Cache.XSDNS}} and its root node name is {{loading}}.
Because the cache stores this placeholder document until the document finishes
78
loading, subsequent calls to synchronous APIs (such as {{getDocument() and getOrOpenDocument()}}) may also return the placeholder document. It is therefore important to check the namespace of the returned document when any code uses the asynchronous APIs.
Once a document finishes loading asynchronously the placeholder document is replaced with the loaded document. This change in value causes the cache to publish a pair of events of action {{Cache.CHANGE}}. If loading the document fails or times out, the placeholder document is instead replaced with another placeholder document. This document also has a URI namespace of {{Cache.XSDNS}}. Its root node name may be either {{error}} or {{timeout}}. If the root node name is {{error}} then the root node has an attribute, also named {{error}}, which contains the XML error message.
If the incoming XML can't be parsed by the {{Request}} instance, the {{getResponseXML}} call fails. One possible cause of failure is invalid XML, while another is an unrecognized content type specified in the HTTP header. The server must set this field in the HTTP header to {{text/xml}} or similar.
If the {{getResponseXML}} call fails but the content is valid XML, you can still parse it by calling the {{getResponseText()}} method and passing the XML string into a {{jsx3.xml.Document}} instance as follows:{code:lang=javascript}var objXML = new jsx3.xml.Document();
79
For more details on the getResponseText() method, see Receiving Non-XML Data.
Non-XML data is useful in many situations. For example, non-XML data can be displayed in the application by setting it as the text property of a jsx3.gui.Block object, or it can be reformatted into CDF for use by a Matrix component. Also, if the data is converted to XML, it can be stored in the local data cache to facilitate data access and management.
Caching Data
Each General Interface application maintains a separate local data cache. If two applications are embedded on a single web page, each has its own cache. This local data cache should not be confused with the browser file cache for temporary Internet files. The General Interface local data cache is an in-memory, JavaScript hash of parsed XML documents that disappears when the browser window is closed. Any XML document, including XML, CDF, and XSL files, can be stored in the local data cache. Controls that display XML data interface with the local data cache by way of the jsx3.xml.Cacheable interface. This class provides methods that link a GUI object and the local data cache data it needs. The GUI object never refers to the data by reference. Only the local data cache references the XML document object, facilitating improved dereferencing and object cleanup. The Share Resources property is an important property of GUI classes that extend Cacheable (Menu, Tree, Matrix, and so on). When the Share Resources property is set to false (default setting) and the GUI object is removed from the General Interface DOM, the associated XML and XSL documents are also removed from the local data cache. Set this property to true if two GUI objects refer to the same document or if the document should remain in the local data cache after the GUI object is removed.
You can cache any XML, CDF, or XSL document using the openDocument() method. The openDocument() method allows you to specify the URL of a file to load and parses the file into a
jsx3.xml.Document instance. To cache the document, provide a second parameter to use as the
Copyright TIBCO Software Inc. All Rights Reserved.
80
jsx3.xml.Document instance. To cache the document, provide a second parameter to use as the
cache ID as follows:
app1.getCache().openDocument ("http://ibiblio.org/bosak/coriolan.xml","someCacheId");
Because this method call is always synchronous, browser performance can be affected if the document is large. To explicitly load a file into cache independently of the openDocument() method, use the setDocument() method. To retrieve a file from cache, use the getDocument() method as follows:
app1.getCache().getDocument("myDocument");
When a document is requested from the local data cache and the document isn't found, the General Interface system queries the shared global cache. For example, if the local data cache doesn't have a document named abc, each of the following calls is equivalent, assuming that the application namespace is app1:
var objXML = jsx3.getSharedCache().getDocument("abc");
or
var objXML = app1.getCache().getDocument("abc")';
To view the contents of the local data cache in General Interface Builder, choose Palettes > Local
Copyright TIBCO Software Inc. All Rights Reserved.
81
To view the contents of the local data cache in General Interface Builder, choose Palettes > Local Data Cache.
82
83
Because CXF is used to define how information is processed, CXF documents are commonly referred to as rules files. The XML Mapping Utility is the design-time tool that creates a rules file, and the jsx3.net.Service class is the runtime engine that executes a rules file. If the rules file specifies that a remote service is involved, the jsx3.net.Service class manages all communications, using its own instance of jsx3.net.Request for the HTTP communications.
84
Mapping Utility user interface is displayed. The XML Mapping Utility has several panels and toolbars: XML Mapping Utility Toolbar Rules Tree Panel Rules Tree Panel Toolbar Rule Profile Panel Settings Panel Mapper Log For definitions of fields in the XML Mapping Utility, see XML Mapping Utility.
85
CDATA
A rule that maps to a CDATA (character data) node. A rule that maps to an element node and which has descendant element, attribute, or CDATA rules. Double-clicking the icon reveals additional rules that are defined by the source WSDL or Schema.
Complex Type
A rule that maps to an element node and which has descendant element, attribute, or CDATA rules.
Data Type The XSD data type of the selected rule, such as string, boolean, decimal, and so on. (large pencil) Element A rule that maps to an element node.
An input or request rule. A rule that has a mapping assigned to it. An operation or transaction rule. An output or response rule. An input rule that repeats. See Repeat When.
Restriction A rule that has a restriction assigned to it. Restrictions are used to validate and restrict user input. See Restrictions. Schema or The root rule in the rules file. WSDL Service (1), (0 - 1), (1-unbounded) The service, which is a collection of operations. Inclusive minimum and maximum number of times this rule can appear in the XML message.
86
running application. See Calling a Data Service. For more information on toolbar buttons, see Rules Tree Panel Toolbar.
Settings Panel
The Settings panel, to the right of the Rules Tree panel, displays fields pertinent to the type of rule selected in the rules tree. If no rule is selected in the rules tree or if multiple rules are selected, the Settings panel is blank. You can use the Settings panel to define how the rule is processed, such as add restrictions, mappings, JavaScript code, and so on. For more information about fields in the Settings panel, see Settings Panel. For more information on using the Settings panel, see Working in the Settings Panel. For additional information and API documentation, hover the mouse over the question mark icon and the APIs icon in the Settings panel.
87
APIs
CDFCONTEXT (Direction: input, output)*---CDF record node being acted upon CDFRECORDS (Direction: input, output)* - CDF records collection being iterated RULENODE (Direction: input, output)* - Current node in the rules tree being processed MESSAGENODE (Direction: input, output)* - Node in the message being processed OBJECTTYPE (Direction: input, output)* - Deprecated. Now evaluates to 'Script' OBJECTNAME (Direction: input, output)* - Deprecated. Will always evaluate to what
FILTER once evaluated to--namely the Script being evaluated FILTER (Direction: input, output)* - Deprecated. Do not use.
setValue(strValue) (Direction: input)* - Equivalent to MESSAGENODE.setValue(strValue) setCDFContext(strXSLQuery) (Direction: input)* - Valid selection query to update CDFCONTEXT. Must return an object reference to a CDF Record node. setCDFRecords(strXSLQuery) (Direction: input)* - Updates record collection to be iterated. Must return a valid jsx3.util.Collection instance containing one or more CDF
record nodes.
disableNamedRule(strNodeName) (Direction: input)* - Disables the named child rule, so that it does not execute until enableNamedRule is called. enableNamedRule(strNodeName) (Direction: input)* - Re-enables the named child rule. disableReferencedRule(objRuleChild) (Direction: input)* - Disables the child rule, so that it does not execute until enableReferencedRule is called. enableReferencedRule(objRuleChild) (Direction: input)* - Re-enables the child rule.
*Contextual variables listed as inputs are available when creating input messages. Outputs are available when processing output messages.
Mapper Log
The Mapper Log displays information about the outcome of parsing the starting source document(s). Different log levels can be selected by clicking on the Adjust Log Level button in the Mapper Log panel. Possible levels, from most detailed to least detailed, include Trace, Debug, Info, Warn, Error, and Fatal. The default level is Info and the XML Mapping Utility resets to this value when closed. The Mapper Log can also be used to view the message exchange when using the Test Interface Tool. For more information, see Mapper Log.
88
WSDL Files
Select WSDL if your source document is a WSDL that defines a Doc Literal or RPC Encoded SOAP service. Specify the location of the WSDL file in the URL field. See Specifying Paths in the XML Mapping Utility.
89
JSON Files
Select JSON if your source document is in JavaScript Object Notation data interchange format. Specify the location of the source document in the URL field. See Specifying Paths in the XML Mapping Utility.
90
workspace. When General Interface Builder is running, this URI resolves relative to the workspace directory.
jsxapp://app/... If the Server instance corresponding to the host portion of the URI is
loaded into memory, the URI is resolved relative to the application base directory ( jsxappbase).
b. Click the Parse Document button to generate the mapping rules file. After you click Parse Document, a new rules file is created. The XML Mapping Utility looks similar to the following:
5. Modify the mapping rules file as desired. For example, remove any extraneous rules as
Copyright TIBCO Software Inc. All Rights Reserved.
91
5. Modify the mapping rules file as desired. For example, remove any extraneous rules as follows: a. Select a rule or rules in the rules tree. Use Shift+click or Ctrl+click to select multiple rules. b. Choose Delete > Delete Selected Rules to delete the rules you've selected. Or choose Delete > Unselected Sibling Rules to delete the unselected rules. For example, select GetHistoricalQuotes (not the singular GetHistoricalQuote) in the Rules Tree panel and choose Delete > Unselected Sibling Rules from the Rules Tree panel menu to remove the other operation rules that were defined by the source WSDL. This helps to reduce the size of your mapping rules file so that it only defines those operations that will be run. For more information, see Modifying Mapping Rules Files. 6. Save the rules file with the .xml extension.
Reordering Rules
Because the rules tree is an execution tree, the order of the rules defines the order of execution. More specifically, the rules are traversed by depth and then breadth. To reorder a rule, simply drag and drop it to a new location in the tree.
92
Adding Rules
To add a rule to the rules file, right-click a rule in the rules tree and choose Add New Rule. Then choose a command from the submenu, such as Element, Attribute, or CDATA. Once you've created a rule, you can modify the profile in the Rule Profile panel. See Working in the Rule Profile Panel.
Cloning Rules
It's also possible to clone any node in the rules tree, including its descendant content. To clone a rule, right-click a rule in the rules tree and choose Clone.
Deleting Rules
If you only need to work with some of the rules that were automatically generated when the source document(s) were parsed, you can delete the unnecessary rules to reduce the clutter in the Rules Tree panel. Reducing the rules in the tree also optimizes the rules file for the web as it only contains necessary rules. This optimized rules file is a key advantage to using the XML Mapping Utility instead of the more verbose WSDL file. Note that deleting rules doesn't affect the source document. To delete a rule and all of its children from the rules tree, select the rule(s) you want to delete and choose Delete > Selected Rules. To delete all unselected sibling rules from the rules tree, select the rule(s) you don't want to delete and choose Delete > Unselected Sibling Rules. Use Ctrl+click or Shift+click to select multiple rules.
Regenerating Rules
The ability to reparse rules is helpful if you've deleted a rule by mistake or you want to remove the rule settings. Often, minor changes to the source WSDL can be handled by downloading a copy of the updated WSDL and replacing the local copy that you used to create the original rules file. Then, right-click the parent rule in the rules tree. Choose Reparse to re-parse from that rule down. When the Reparse Selected Branch dialog displays, click the Reparse button to reparse the rule. The rule is returned to its original state and all mappings are lost. In some situations the reparse will fail. If that occurs, select the rule in the rules tree, choose the Rule Node Profile radio button, and write your own XPath in the Source Path field to recreate the binding between the rule in the rules tree and the Schema definition in the source document from which it originates. For example, if you parse the default WSDL Address.wsdl, the ReturnCityState element maps to the Schema node at this address:
//jsx3:schema[@targetNamespace='http://ws.cdyne.com/']//jsx3:element[@name='ReturnCityState']
The above address is brittle, because if an additional element is added to the Schema, it can corrupt the absolute addressing. In such a case, simply edit the XPath to use an XPath address that is less brittle. For example,
//jsx3:element[@name='ReturnCityState']
93
When authoring your own XPath for a WSDL document, use the jsx1 prefix to point to any node in the source document belonging to the namespace, http://schemas.xmlsoap.org/wsdl/. Use jsx3 to resolve to the namespace, http://www.w3.org/2001/XMLSchema. For all other source document types (XHTML, Schema, XML, etc), the prefix is an incremented value (jsx1, jsx2, jsx3, etc) that reflects the order in which the namespace was first declared in the source document.
Adding Mappings
Rules that descend from input or output rules can be mapped to GUI components, as well as to CDF documents, records, and attributes. For example, you can map user input in a text field to a rule in your rules file and then send this data to a web service in the outgoing message. Incoming data from the web service can then be mapped to a CDF document, allowing the server's response to be displayed in the user interface. There are several ways to add mappings: Drag and drop a GUI component from the Component Hierarchy palette to a rule in the Rules Tree panel. See Mapping GUI Components to Mapping Rules. Select a rule and create a mapping using the Map menu. See Mapping Response Data to CDF GUI Components. Select a rule and set the mapping in the Mapping table in the Settings panel. See Adding a Mapping to the Mappings Table. For more information on mapping types, see Message Rules.
94
To modify the rule profile in the rules tree, do the following: 1. Select the rule you want to modify in the Rules Tree panel. 2. Select the Rule Node Profile radio button below the Rules Tree panel. 3. Click in the Value field next to the name you want to modify. 4. Type in a value. 5. Generate a test message to test the impact of changes to the rule profile. To generate a test message, right-click an input or output rule in the Rules Tree panel and choose Generate Sample Message. For field definitions, see Rule Node Profile.
95
When you use the SCRIPT method, the XML Mapping Utility uses a SCRIPT tag for the transport instead of the standard XMLHTTP control. With the SCRIPT method, you can set an additional field to specify that the service uses JSONP (JSON with padding). When this field is set, the service class appends an additional parameter to the URL in the form
callback={method}
This allows for flexibility when using JSON Services that are also available as JSONP
Copyright TIBCO Software Inc. All Rights Reserved.
96
This allows for flexibility when using JSON Services that are also available as JSONP Services---you can use the same endpoint URL, but implement different behaviors. If the given JSONP Service expects the name of the callback parameter to be something different than callback, use the runtime API call, setJSONP, to pass the parameter name that is expected by the given JSON Service. For example, Yahoo! Pipes supports the parameter name "_callback" for its implementation of JSONP. Therefore, when calling Pipes, make sure to set the true name of the callback before sending the request:
objService.setJSONP("_callback"); objService.doCall();
Note that the following two statements are equivalent, because the default JSONP name used by the system is " callback ":
objService.setJSONP(true); objService.setJSONP("callback");
You can also implement a callback of your own by directly modifying the endpoint URL to call the named function. In such situations, pass false to this method, so that the transport will not attempt any form of automated callback. If you implement your own callback handlers, you must manually conclude the service call with a call to the Service method doRespond, by passing the JSON object returned from the Service back to the mapper.
97
For more information on fields in the Settings panel, see Input Rules.
Stub URL
To enable the Stub URL field, click the Enable button next to the field. The Stub URL field is typically used in conjunction with the Stub Path field to support SOAP-based web services. When SOAP is used, each request document is encapsulated by a SOAP Envelope. The XML Mapping Utility treats the Envelope as a static document into which the actual request is placed. For example, the default stub used by the XML Mapping Utility is as follows:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
This document is generic enough to encapsulate the majority of SOAP messages and it's recommended that you use it. However, if this default document does not contain enough information, you can specify the URL for a static stub of your own. For example, you might also need to include a SOAP Header in addition to a SOAP Body element in the Envelope.
98
The Stub URL value can be updated at runtime using the API call, setOutboundStubURL. If more control is needed over the stub document and its structures, you can provide a parsed jsx3.xml.Document instance of your own by calling the setOutboundStubDocument() method.
Stub Path
When the stub document changes, it is often necessary to update the Stub Path to reflect the XPath address for the node in the Stub document to which the message will be appended. To enable the Stub Path field, click the Enable button next to the field. Use the Stub Path field in conjunction with the Stub URL field. Type in a valid XSL query that describes where to place the generated document in the Stub document. For example, the following document is generated when the GetHistoricalQuotes operation is called in the WSDL Mapping 2 sample:
<jsx1:GetHistoricalQuotes> <jsx1:Identifiers>ibm,yhoo,goog,tibx</jsx1:Identifiers> <jsx1:IdentifierType>Symbol</jsx1:IdentifierType> <jsx1:AsOfDate>3-21-06</jsx1:AsOfDate> </jsx1:GetHistoricalQuotes>
The combination of the default Stub URL(GI_HOME_/GI_Builder/JSX/stubs/soap.xml) and Stub Path(/SOAP-ENV:Envelope/SOAP-ENV:Body) results in the following document being sent:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <jsx1:GetHistoricalQuotes xmlns:jsx1="http://www.xignite.com/services/"> <jsx1:Identifiers>ibm,yhoo,goog,tibx</jsx1:Identifiers> <jsx1:IdentifierType>Symbol</jsx1:IdentifierType> <jsx1:AsOfDate>3-21-06</jsx1:AsOfDate> </jsx1:GetHistoricalQuotes> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
This value can be updated at runtime using the API call, setOutboundStubPath.
onBeforeSend
Enter one or more JavaScript statements in this field to execute immediately before the request message is sent. For example, if you want to output the XML request to the System Log before sending it, you enter the following statement, where the keyword, this, refers to the jsx3.net.Service instance:
jsx3.log(this.getOutboundDocument().getXML());
99
For more information on fields in the Settings panel, see Output Rules.
Stub URL
The XML Mapping Utility provides a static mode that allows you to test against a typical service response. This is useful in situations where the service isn't built yet or is inaccessible. Use the Stub URL field to specify an XML document that contains a response for testing purposes. To use the static mode feature, complete these steps: 1. Save a valid XML document (the typical response) and enter the URL in the Stub URL field. 2. Do one of the following to set the static mode: Choose Project > Project Settings and change the Mode option on the Deployment panel of the Project Settings dialog from Live to Static, and refresh the browser to reload the project. See Deployment Panel. Call setMode(0) on the jsx3.net.Service instance to make only that instance run in static mode while leaving the remainder of the project in live mode. Now when transactions are run by a service, a request isn't sent. Instead the sample document is processed as if the remote service returned it.
Copyright TIBCO Software Inc. All Rights Reserved.
100
is processed as if the remote service returned it. This URL can also be set at runtime using the API call, setInboundURL.
onAfterReceive
JavaScript statements entered in the onAfterReceive field execute immediately after the response message is received and before the mappings are applied. This script executes in context of the Service instance. This means that the keyword, this, refers to the Service instance. For example, if you want to output the XML response to the System Log palette each time the service responds, you could write: jsx3.log(this.getInboundDocument().getXML());
To implement the above transformation, assume the above stylesheet is named multiRefConverter.xsl. You would enter the following code in the onAfterReceive field for your given operation:
/* get the document just returned from the service */ var myXML = this.getInboundDocument(); /* load the xslt that will convert the axis multiref structure to a more concrete/literal format */ var myXSL = (new jsx3.xml.XslDocument()).load("multiRefConverter.xsl"); /* transform xml to filter */ var newXML = myXSL.transformToObject(myXML); /* replace the server's document with the new, transformed document */ this.setInboundDocument(newXML);
Copyright TIBCO Software Inc. All Rights Reserved.
101
For more information on fields in the Settings panel, see Message Rules.
102
For more information on mapping types, see Mappings. For more information on mapping GUI components, see Mapping GUI Components to Mapping Rules. For information on mapping response data, see Mapping Response Data to CDF GUI Components.
Restrictions
When Schema or WSDL are used as the input, any restrictions in the input source file display in the Restrictions table of the Settings panel. Rules that have restrictions are indicated with a Restriction icon in the rules tree.
You can also add restrictions on a rule. For example, you might restrict user input to a five-digit number for a field that requires a zip code. To add a restriction: 1. Select a message rule in the Rules Tree panel to display the Restrictions table in the Settings panel. 2. Click the down arrow in a blank Type field of the Restrictions table and select a type, such as maxLength. 3. Type a value in the Value field, such as 5. This would limit user input to a maximum of five characters. For more information on restriction types, see Restrictions.
Repeat When
The Repeat When field is only applicable to outbound (input) messages. Enter one or more JavaScript statements in the Repeat When field. As long as this field evaluates to true, this specific rule is rerun. The Repeat When field is typically used by mapping rules that convert a JavaScript array into an XML Node-set in the outgoing message. Conceptually, this feature is similar to a do-while loop, where execution will happen at least once and continue as long as the while (Repeat When) statement is true. If your mapping rule was originally created from a source WSDL, you can easily identify message rules that are part of a collection by looking at the Restrictions table. The rule is a good candidate for using the Repeat When field if it declares a maxLength restriction with a value of unbounded, *, or greater than 1.
Example 1
For example, if you write a function similar to this:
Copyright TIBCO Software Inc. All Rights Reserved.
103
and enter a call to the function in the Repeat When field for an addressToCheck rule in the WSDL Mapping 1 sample:
window.getNext();
the JavaScript code iterates through the function three times and three records are added to the XML message for the rule. This sample message shows the three added records.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <jsx1:StandardizedAddress xmlns:jsx1="http://ws.cdyne.com/"> *<jsx1:addressToCheck>???</jsx1:addressToCheck>* *<jsx1:addressToCheck>???</jsx1:addressToCheck>* *<jsx1:addressToCheck>???</jsx1:addressToCheck>* <jsx1:LicenseKey> <rule_node/> </jsx1:LicenseKey> </jsx1:StandardizedAddress> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
Example 2
Another example might be if you have an array of ids that you need to send to a server. You can include a Repeat When statement, so that the XML Mapping Utility knows how to iterate through this array. For example, the given web service might expect the following XML, where the id field repeats to contain as many ids as necessary:
<ids> <id/> </ids>
A simple approach is to use the Array.shift() method on a Script mapping that you will bind to the id rule. For example, if you have a global array named myArray, the Script mapping for the id rule would look like this:
setValue( myArray.shift() );
Because the shift method will remove the array element as soon as it is read, you can be certain that the XML Mapping Utility will only loop as many times as it has array elements. This results in only one node in the outgoing message for each item in the array:
Copyright TIBCO Software Inc. All Rights Reserved.
104
Also note that CDF mappings automatically repeat when necessary. For more information on CDF GUI components, see Mapping Response Data to CDF GUI Components.
105
106
2. Arrange the Component Hierarchy palette and the Rules Tree panel so that components and elements are visible. 3. Drag objects from the Component Hierarchy palette and drop them onto a rule in the Rules Tree panel to bind GUI components to rules. Note that the mapped rule now displays a Mapping icon in the rules tree. For example, drag the symbol component from the Component Hierarchy palette to the Identifiers rule in the Rules Tree panel of the XML Mapping Utility. A mapping is created between the GUI component and the target rule. Note the following changes in the Settings panel on the right: A mapping is added to the Mappings table on the right and default values are populated. The type of mapping is displayed in the Type column of the Mappings table. The value of the mapping is displayed in the Path/Value column of the Mappings table.
Other types of mappings can be created by selecting a mapping type and typing a value in the Path/Value field. For example, a rule could be mapped to a value specified by a JavaScript method call or to a CDF document, record, or attribute. For information on mapping types, see Message Rules. A Script mapping can be used to specify JavaScript code that manipulates message structure or field data. For more information on this type of mapping, see Using Code with Data Services. Structured rules are typically mapped to CDF documents, records, and attributes. For more information on this type of mapping, see Mapping Response Data to CDF GUI Components. 4. Save the rules file as follows: a. Click the Save button at the top of the XML Mapping Utility.
Copyright TIBCO Software Inc. All Rights Reserved.
b. Navigate to the rules folder and type the filename with the .xml extension in the
4.
107
a. b. Navigate to the rules folder and type the filename with the .xml extension in the field at the bottom of the dialog. The rules folder is automatically created in your project folder. However, rules files can be stored in any location in the project directory. c. Click Save in the Save File dialog to save the file. Now that you've defined the mappings between the GUI components and the data exposed by the service, you need to generate the JavaScript function to call the service. Then specify this event in the Execute event of a component, such as a button. To generate the JavaScript code, see Calling a Data Service.
108
4. Select Map > DOM (map and create) from the Rules Tree panel menu.
The XML Mapping Utility generates the components and a Mapping icon tree indicates that a rule is mapped.
in the rules
5. Save the mapping rules file with the .xml extension. You can also automatically map and generate simple GUI components for the Output (response) rule. Now that the mappings between the GUI components and the data exposed by the service are defined, you need to generate the JavaScript function to call the service. Then specify this function in the Execute event of a component, such as a button. To generate the JavaScript code, see Calling a Data Service.
109
110
jsx3.lang.Package.definePackage( //the full name of the package to create "eg.service", //name the argument of this function function(service) { //call this method to begin the service call //(eg.service.callGetHistoricalQuotes();\) service.callOperation_Name = function() { var objService = Server_Name.loadResource("Project_Resource_File_Id"); objService.setOperation("Operation_Name");
//subscribe and call objService.subscribe(jsx3.net.Service.ON_SUCCESS, service.onOperation_NameSuccess); objService.subscribe(jsx3.net.Service.ON_ERROR, service.onOperation_NameError); objService.subscribe(jsx3.net.Service.ON_INVALID, service.onOperation_NameInvalid); objService.doCall(); }; service.onOperation_NameSuccess = function(objEvent) { //var responseXML = objEvent.target.getInboundDocument(); objEvent.target.getServer().alert("Success","The service call was successful."); }; service.onOperation_NameError = function(objEvent) { var myStatus = objEvent.target.getRequest().getStatus(); objEvent.target.getServer().alert("Error","The service call failed.The HTTP Status code is: " + myStatus); }; service.onOperation_NameInvalid = function(objEvent) { objEvent.target.getServer().alert("Invalid","The following message node just failed validation:\n\n" + objEvent.message); }; } );
where Operation_Name is the name of the SOAP operation to invoke and Project_Resource_File_Id is the ID of the rules file. Function names and alert text can be customized. The function, service.call _Operation_Name_Success, is called when the data service responds. Communication between the application and the data service is asynchronous, so this function can be used for notification of a response. 5. Save the JavaScript file.
111
From the above information, you know that an error occurred on line 47, within the function eg.service#doCallYetAgain(). You also know the order of the call stack and whether it involved static or instance methods. Had you not used definePackage, the output to the error log would look something like this:
10:36:13.443 global (ERROR) - Uncaught Exception: 'xp' is undefined (line: 47, file: file://C:\tibco\gi\GI_Builder.hta) at anonymous() at anonymous() at anonymous()
For more information on how to use General Interface package APIs, see jsx3.lang.Package in General Interface API Reference (Help > API Documentation).
112
113
To map response elements to CDF, complete the following steps: 1. In the Rules Tree panel of the XML Mapping Utility, select the immediate parent of the element that corresponds to a record in the CDF document. In this example, the parent element is GetHistoricalQuotesResult, because it contains the repeating HistoricalQuote elements that will map to records in the CDF document. 2. In the Mappings table of the Settings panel, select CDF Document from the drop-down list in the Type column of the Mappings table. 3. Type a cache ID string for the CDF document in the Path/Value column. For the WSDL Mapping 2 example, type historicals. This value becomes the cache ID of the CDF document, which appears in the Local Data Cache palette after the response is received and inbound mapping logic is applied. If the file exists, it's overwritten. If the file doesn't exist, a new file is created in the cache. In the WSDL Mapping 2 example, the rules file looks like this:
4. Select the element in the Rules Tree panel that corresponds to a record in the CDF document. In the WSDL Mapping 2 example, the element that corresponds to a CDF record is HistoricalQuote, which is the repeating rule. 5. Select CDF Record from the drop-down list in the Type column in the Mappings table. It's not necessary to specify a value in the Path/Value column for this exercise.
114
You can also select an element in the rules tree and choose Map > CDF Record.
Although the Path/Value field is not required, it can be used to support recursion or hand off processing to another rule. For example, if there is another rule in your mapping rules file that has a CDF Record mapping, you can enter the jsxid for that rule. To find the jsxid (Rule ID), select the rule that you wish to call and click the Rule Node Profile radio button. When a repeating rule is mapped to a CDF record, by default the rules file automatically iterates through each corresponding node in the concrete message. In the WSDL Mapping 2 example, the rules file looks like this:
1. Select an element to map in the Rules Tree panel. For example, select Date. 2. Select CDF Attribute from the Type drop-down list in the Mappings table. 3. Type a string value in the Path/Value field. This value becomes the attribute name in the CDF document. For example, type Date for the Date element. You can also select an element in the Rules Tree panel and choose Map > CDF Attribute. The attribute name is automatically generated in the Path/Value field.
In the WSDL Mapping 2 example, the rules file looks like this:
4. Follow the same process to create mappings for other elements to include in the CDF document: select the element, select CDF Attribute as the Type, and enter a name for the
Copyright TIBCO Software Inc. All Rights Reserved.
115
4. document: select the element, select CDF Attribute as the Type, and enter a name for the corresponding CDF attribute. To add multiple CDF attribute mappings at once, use Ctrl+click or Shift+click to select multiple rules and select Map > CDF Attribute in the Rules Tree panel menu.
In the WSDL Mapping 2 example, the rules file looks similar to this:
If the response has nested rules, you can replicate the nested structure using CDF Record and CDF Attribute mappings. The jsxid attribute, which is required in every CDF document, acts as a key. You can map an existing element that acts as a key value, such as a date or other unique value, to jsxid. If no such mapping exists, the XML Mapping Utility automatically adds a jsxid attribute to the CDF document and generates a unique value. 5. Save the mappings file.
116
3. Select the GUI object in the Component Hierarchy palette that will display the data series. In the WSDL Mapping 2 example, the object is a column in the matrix, such as date, security, open, and so on. 4. Open the Properties Editor palette and type the attribute name in the Value field of the Att Name property. In this example, choose date in the Component Hierarchy palette and type Date, the attribute name, in the Att Name field to map the date component to the CDF Date attribute.
5. Repeat the process for other GUI objects until all series mappings are complete: select each object in the Component Hierarchy palette and type the appropriate CDF attribute name in the Value field of the Att Name property. Next, you need to test the rules file to be sure the mappings are correct. To test the rules file, see Running a Quick Test.
117
Setting Up a Test
To set up a test, specify values for each mapped element to simulate user input. There are two ways to simulate input: Specify data in user input fields in the work area. Specify values in the Mappings table. To specify values in the Mappings table, complete these steps in the XML Mapping Utility: 1. Select a rule in the Rules Tree panel. 2. In the Mappings table of the Settings panel, select Script from the drop-down list in the Type column. 3. Type the JavaScript setValue function in the Path/Value column and specify a value, setValue("value_") ; The setValue() method is useful for specifying constants normally specified by a user at runtime or a value that is calculated from user input. 4. When all values are specified, click the Save button.
2.
118
When the response is received, a file with the specified name displays in the Local Data Cache palette. This file exists in the cache instance used by the current component. In the WSDL Mapping 2 example, the file name in the Local Data Cache palette is historicals. If you open this file, you'll see the response data from the service. 3. Return to the work area to see the updated information in the mapped component. If the updated information isn't displayed, complete these steps: a. Select the top-level GUI component that consumes the data in the Component Hierarchy palette. In the WSDL Mapping 2 example, select the gridResults component. b. Click the Repaint button in the Component Hierarchy palette.
The Test Interface Tool is designed to guide you through the test sequence. The Create, Send, Receive, and Apply tabs correspond to phases of sending and receiving XML messages. Clicking a tab displays data that is relevant to the current test phase. Before running a test, you can set breakpoints at various steps in the test sequence or you can also test a rules file without breakpoints. For more information, see Setting Breakpoints.
119
Mapper Log
You can also use the Mapper Log to view the results of a message exchange. Use the Adjust Log Level button to select a log level before you begin testing.
Running a Test
To run a test in the Test Interface Tool, complete these steps: 1. Click the Test button on the Rules Tree panel toolbar to open the Test Interface Tool.
2. Select the operation to test from the Select drop-down list at upper left.
120
The Create tab displays mappings for the outbound message and the following fields: Rule Name contains the name of the element. Type shows the type of object that is mapped. Path/Value contains the GUI component name or any associated JavaScript code for this mapping. Post-Mapping Filter/Handler contains filter code to execute before sending the message. 3. Click the Start Test button next to the Outbound Mappings label to start the test. If you didn't set any breakpoints and there aren't any errors, the test runs and cycles through each tab: Send, Receive, and Apply. When the test is complete the Create tab displays again. 4. If a breakpoint was set, the test advances to the Send tab. For more information, see Setting Breakpoints.
The Send tab displays the outbound message and the following fields: URL contains the URL specified in the WSDL file. HTTP Headers contains header content for the message. The header text can be customized by editing this value. Name and Password are used for services requiring HTTP authentication.
Copyright TIBCO Software Inc. All Rights Reserved.
121
Name and Password are used for services requiring HTTP authentication. Method defines the method for contacting the Service. The most common are GET and POST. The contents of the outbound and inbound messages can be saved to local files for testing purposes. By mapping the saved inbound file and specifying the application mode as Static on the Deployment panel of the Project Settings dialog (Project > Project Settings), you can continue developing your application without a data service connection. For more information, see Deployment Panel. 5. If a breakpoint was set, click the Resume button to advance to the next step. The outbound message is sent to the data service, and the response is displayed in the Receive tab. Because the Receive tab doesn't have a breakpoint, the test continues to the Apply tab. Click the Receive tab to see the response.
The Receive tab displays the following fields: HTTP Headers contains the HTTP headers. HTTP Status contains the message status, such as 200. Response contains the response. If the response isn't received, testing can still proceed with a simulated response message. Click the Generate Alternate Inbound Message button to the left of the Response field. A response message for the specified operation is copied to the Response field. 6. If the Test Interface Tool doesn't automatically advance to the Apply tab, click the Apply tab to advance to the next step.
122
The Apply tab displays the following fields: Pre-Mapping Filter/Handler contains filter code to execute on the inbound document. Inbound Mappings contains mappings of response rules to GUI components and inbound filtering logic, if any. This is the final step in the testing process. If filtering logic and mappings executed without errors, the Create tab displays to allow you to start another testing cycle. For a step-by-step example of running a test with the Address Lookup example, see Testing Mappings.
Setting Breakpoints
Before running a test, you can set breakpoints for viewing request and response messages at each step in the process. Breakpoints can be set at the following steps: Before applying filtering code, if specified, to the outbound message Before sending the outbound message to the data service Before applying filtering code, if specified, to the inbound message Before executing inbound mappings You can also test a rules file without breakpoints. However, it is usually helpful to view the test results after each step. When advancing from one breakpoint to the next, you can return to the previous breakpoint to retest only that step in the process. After modifications to mapping rules, changes can be tested from the last breakpoint. To set a breakpoint and run a test with breakpoints in the Test Interface Tool, complete these steps: 1. Click any tab that displays a Breakpoint button , such as the Create, Send, or Apply tab. 2. Click a Breakpoint button to set a breakpoint. 3. Click the Create tab and run the test as described in Running a Test. The test stops at any step that has a breakpoint set. 4. Click the Resume button to advance to the next step.
Copyright TIBCO Software Inc. All Rights Reserved.
123
Setting Filters
Filters can be applied to messages before an input message (request) is sent or after an output message (response) is received and before the mappings are applied. This is useful when you want to modify requests and responses. You can enter JavaScript code to run as a filter on message rules. There are two ways to set a filter for message rules: Input message rules Post-Mapping Filter/Handler field Enter JavaScript code in this field on the Create panel of the Test Interface Tool to filter the input message during testing. onBeforeReceive field Enter JavaScript code in this field of the Settings panel of the XML Mapping Utility. Code entered in this field is always run on the message. Note that code entered here is also automatically displayed on the Create panel of the Test Interface Tool and runs during testing. Output message rules Pre-Mapping Filter/Handler field Enter JavaScript code in this field on the Apply panel of the Test Interface Tool to filter the output message during testing. onAfterReceive field Enter JavaScript code in this field of the Settings panel of the XML Mapping Utility. Code entered in this field is always run on the message. Note that code entered here is also automatically displayed on the Apply panel of the Test Interface Tool and runs during testing. Filters are useful for manipulating input and output messages as they travel between the client and the server. For example, the XML Mapping Utility doesn't support multiRef structures that are sometimes used to describe SOAP messages on Apache Axis servers. However, you can use the onAfterReceive event handler to manipulate the output message from the server before running the inbound mapping rules. Since you can't control your server environment, you could write an XSLT that would convert the multiref indirection to a supported XML Mapping Utility format. This transformation would occur on the client after the message is received. For more information on this multiRef example, see onAfterReceive multiRef Example.
Further Information
For more tutorials and sample applications, see: General Interface samples workspace/JSXAPPS/samples Developer Network at http://www.generalinterface.org Sample Projects Video Tutorials
124
Handling Errors
When an operation generates an error, the error information is returned to the Request object for the response. You can write a JavaScript function that gets the error information, adds business logic for handling the error scenario, and displays the error to the user. When errors occur, they can take several forms: HTTP errors can be determined by calling getRequest on the Service instance and then querying the jsx3.net.Request object for its status (getStatus) and status description ( getStatusText). SOAP faults can be processed by mapping to the fault rules that are created by the XML Mapping Utility when the WSDL is parsed (assuming the WSDL defines them). Formatting errors, such as a string in a number field or an enumerated value not being entered, can be determined by subscribing to the ON_INVALID subject for the service instance. When an error is encountered during message generation, the specified callback function is notified. JavaScript errors display in the System Log palette for General Interface Builder.
125
126
After you click the Parse Document button, you see the Rules Tree panel as shown here:
127
Defining Mappings
In this step, you'll define mappings between the GUI components of the myAddressLookup application and the data exposed by the web service. The Address.wsdl file used in the myAddressLookup project defines several operations. Because you only use one operation for the myAddressLookup application, ReturnCityState , you can remove all other operations for the rules file as they aren't needed.
2. Delete all other operations by selecting Delete > Unselected Sibling Rules. 3. Arrange the Component Hierarchy palette and the Rules Tree panel so that components and mapping rules are visible. 4. Create a mapping between the txtZipcode component and the zipcode rule as follows: a. Expand the ReturnCityState rule in the Rules Tree panel. b. Expand the Input (request) rule and double-click the ReturnCityState child rule. The ReturnCityState request has two input rules: zipcode and LicenseKey. c. Drag the txtZipcode component from the Component Hierarchy palette to the zipcode rule in the Rules Tree panel. The following mapping is created in the
Copyright TIBCO Software Inc. All Rights Reserved.
c. zipcode rule in the Rules Tree panel. The following mapping is created in the rules tree.
128
Notice in the Mappings table to the right that the Type is DOM (Document Object Model), representing a mapping between a GUI component and a rule in the rules tree. The value is txtZipcode, the name of the GUI component.
Next, you'll use the setValue() method to set the license key value to use the evaluation license ("0"). The evaluation license provides limited access to the service during testing. If the designated number of requests is exceeded, an error is returned. 5. Set the value for the license key as follows: a. Click the LicenseKey rule in the Rules Tree panel. b. Select Script from the drop-down list in the Type column of the Mappings table.
129
c.
Because the license key value, zero, is a JavaScript string, it must be enclosed in quotation marks.
130
2. Click OK in the Code Generator prompt, which displays a message that the JavaScript code has been copied to the clipboard. 3. Click the Minimize button in the XML Mapping Utility. 4. Click the logic.js tab in the General Interface Builder work area. This file contains business logic for your application. It should be empty except for a comment line. 5. Delete the comment line and press Ctrl+v to paste the contents of the clipboard into logic.js. The JavaScript code in the logic.js file should look like the following:
jsx3.lang.Package.definePackage( "eg.service", //the full name of the package to create function(service) { //name the argument of this function //call this method to begin the service call //(eg.service.callReturnCityState();\) service.callReturnCityState = function() { var objService = myAddressLookup.loadResource("GetCityandState_xml"); objService.setOperation("ReturnCityState"); //subscribe and call objService.subscribe(jsx3.net.Service.ON_SUCCESS, service.onReturnCityStateSuccess); objService.subscribe(jsx3.net.Service.ON_ERROR, service.onReturnCityStateError); objService.subscribe(jsx3.net.Service.ON_INVALID, service.onReturnCityStateInvalid); objService.doCall(); }; service.onReturnCityStateSuccess = function(objEvent) { //var responseXML = objEvent.target.getInboundDocument(); objEvent.target.getServer().alert("Success", "The service call was successful."); }; service.onReturnCityStateError = function(objEvent) { var myStatus = objEvent.target.getRequest().getStatus(); objEvent.target.getServer().alert("Error","The service call failed. The HTTP Status code is: " + myStatus); }; service.onReturnCityStateInvalid = function(objEvent) { objEvent.target.getServer().alert("Invalid","The following message node just failed validation:\n\n" + objEvent.message); }; } );
After the Find City and State button is clicked and the web service is called, the function displays an alert dialog containing the text The service call was successful. 6. Right-click the logic.js tab and select Save and Reload.
Copyright TIBCO Software Inc. All Rights Reserved.
131
6. Right-click the logic.js tab and select Save and Reload. This command saves the file with the modified contents and also loads the file into memory, making the methods available without requiring the browser window to be refreshed.
Testing Mappings
The XML Mapping Utility includes features for verifying inbound and outbound messages generated using a rules file. The entire test sequence consists of executing outbound mappings, generating the outbound message, sending the message, receiving the response, and executing inbound mappings. Outbound and inbound filtering logic can also be entered and verified. To test the address example, complete these steps: 1. Simulate user input by manually typing a valid 5-digit or 9-digit zip code in the Type Zip Code field in the work area. For example, type 11357 in the Type Zip Code field. 2. Select the LicenseKey input rule in the Rules Tree panel in the XML Mapping Utility. Confirm that you selected Script as the Type and entered setValue("0") in the Path/Value column of the Mappings table. If you haven't, refer to the instructions in Defining Mappings.
132
3. Click the Test button on the XML Mapping Utility toolbar to open the Test Interface Tool. 4. Select ReturnCityState from the drop-down list at upper left. 5. Before testing the mappings, insert breakpoints for viewing request and response messages at each step in the process. a. Click the Send tab and click the Pause Before Sending the Message button to insert a breakpoint. b. Click the Apply tab and click the Pause Before Executing Inbound Mappings button next to the Inbound Mapping header to insert a breakpoint. 6. Click the Create tab. The Outbound Mappings panel lists the bound request parameters and mapping information.
7. Click the Start Test button next to the Outbound Mappings header to begin testing the mappings. When the message is generated, the message displays in the Send tab.
8.
133
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <jsx1:ReturnCityState xmlns:jsx1="http://ws.cdyne.com/"><jsx1:zipcode>11357 </jsx1:zipcode><jsx1:LicenseKey>0</jsx1:LicenseKey> </jsx1:ReturnCityState> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
The zip code you specified in the dialog should display as the contents of the jsx1:zipcode element. For example,
<jsx1:zipcode>11357</jsx1:zipcode>
If the message code is incorrect, return to the XML Mapping Utility and verify that bindings are correctly specified before proceeding. 9. Click the Resume Test (Send Message) button next to the URL field. The outbound message is sent to the web service. When a response is received, the message displays in the Receive tab and the XML Mapping Utility automatically advances to the Apply tab. 10. Click the Receive tab to view the inbound message. City and state information is returned in the City and StateAbbrev elements. However, this data has not yet been bound to any text boxes. If you view the application in the work area, the City and State fields are still blank.
11. Click the Apply tab. The Test Interface displays inbound mappings to text boxes.
134
12. Click the Resume (Execute Inbound Mappings) button next to the Inbound Mappings header. In the work area, you can see that inbound mappings are applied to text boxes. The City and State fields have a blue background because the fields are disabled. This is to prevent users from entering data in these fields.
The testing cycle for this data service configuration is complete, and the XML Mapping Utility cycles back to the Create tab. This concludes the tutorial. For other examples of connecting to web services, see samples in workspace/JSXAPPS/samples and on the Developer Network at http://www.generalinterface.org.
135
3.
136
4. Add two text boxes to the mapping container---drag two text boxes from the Form Element component library to the cdf mapping container, and name them T1 and T2:
5. Look at the Properties Editor for the cdf element---the XML String property contains this Value:
<data jsxid="jsxroot"> <record jsxid="1" first="john" last="public" middle="q"/> </data>
Copyright TIBCO Software Inc. All Rights Reserved.
137
This is the default test document that is provided with the control. Like all other controls that implement the Cacheable interface, this control will parse this string of XML and set it in the local cache, using a unique ID (or one assigned by the developer if applicable). 6. Open the Local Data Cache, and you'll see that the CDF mapping container has put the _jsx_1_4_XML file there:
7. Double-click the XML file name to open it in the work area, then click the Formatted Source XML button to see the formatted XML:
138
3. Click the text box named T2. 4. In the Properties Editor, type middle in the Value field of the CDF Attribute Name. The letter q appears in the T2 text box of the CDF mapping container, because the value q is assigned to the attribute middle in the XML file.
6. In the Properties Editor for the T1 component, change the CDF Record Id value from 1 to 2, to change the name in the T1 text box:
139
This exercise illustrates how you can make each form be a separate data store---it always reads the value of the CDF Record Id, regardless of how the CDF control for the form is mapped. A CDF container can: Inherit a document from an ancestor CDF, or it can provide its own document. Map the records of an ancestor CDF, or provide its own mapping. You can continue nesting components inside components in the CDF mapping container, so that each nested component becomes a separate data item. Whichever container is the last in the nested chain determines the final mapping.
To use the API to set a property: 1. Open Tools > JavaScript Console. 2. Type the appropriate API syntax and values for the property. In this example, the T1 text box originally contains the value of CDF record ID 2, which is jane. Using the API setCDFId, we change the T1 text box value from record 2 ( jane) to record 1 (john ):
140
Application Design
One of the critical phases of software design is application design. When designing your application, it's important to consider the following: What are the end-user requirements? What tasks will the user need to accomplish? What is the work flow? How easy is the application to use? Application design includes application architecture, user interface design, and component design. If this phase of application development is neglected, usability and performance can be adversely affected. For example, poor performance can occur if the application has a poorly designed, complicated user interface and if the application uses components that aren't designed properly. While designing your General Interface application, consider the following best practices.
141
Load resources asynchronously Asynchronously load JavaScript files using the jsx3.app.Server.loadInclude() method Asynchronously load an XML document and store it in the local data cache using the jsx3.app.Cache.getOrLoadAsync method Asynchronously load an XML document using the jsx3.xml.Document.setAsync() method Issue a request asynchronously by passing bAsync=true to the jsx3.net.Request.open() method For more information, see General Interface API Reference. For more information, see General Interface Component Guide.
142
Search Components in the DOM Efficiently Exclude Logging Messages JavaScript Code Remove Unused JavaScript Code Avoid Initializing Unused Variables Replace Old and Deprecated APIs with More Efficient APIs Replace JavaScript Manipulation of CDF with XSL Transformations Use jsx3.net.Service.compile() Avoid Excessive String Concatenations Identify Slow Functions Calls Faster Load Times Upgrade to the latest version of General Interface Upgrade Browsers Load from Cache Split CDF Documents Create Custom General Interface Builds Benchmarking Performance Review Component Statistics Use the General Interface Debug Build Use General Interface Performance Profiler Use JavaScript Profiling Tools Use General Interface Test Automation Kit
Upgrade Browsers
When possible, use the latest browsers supported by General Interface. Also, as you develop your application, benchmark your application in all browsers and versions used by your end users. Benchmarking in all browsers prevents unexpected performance issues after deployment. For example, Internet Explorer 6 is slower than Firefox. Note that subsequent Internet Explorer releases are significantly faster than Internet Explorer 6.
143
JavaScript Code
Use the following best practices when developing JavaScript code for your application.
to List:
for (var it = objList.iterator();it.hasNext();\){ var x = it.next(); }
Copyright TIBCO Software Inc. All Rights Reserved.
144
GUI components that implement jsx3.xml.Cacheable have built-in properties for XSL transformations. See the XML Transformers property in the Properties Editor palette and jsx3.xml.Cacheable.setXMLTransformers() in General Interface API Reference.
Use jsx3.net.Service.compile()
Use the jsx3.net.Service.compile() method to compile the CXF rules for a service instance to an equivalent XSLT document. This enables much faster performance than using the DOM-based iterator (default) to convert the XML response document into a CDF Document type. Call this method immediately before or after the doCall() method for best performance. For more information, see jsx3.net.Service.compile() in General Interface API Reference.
API Usage
When writing JavaScript code for your application, use the following best practices.
Minimize Repainting
The on-screen rendering of HTML is often the slowest aspect of browser-based applications. Using efficient repaints can make your application faster and more responsive to user input.
Copyright TIBCO Software Inc. All Rights Reserved.
145
Follow these best practices for repainting: Look for unnecessary repaints in your JavaScript code and remove them. Use the General Interface debug build to identify multiple repaints. See Use the General Interface Debug Build. Repaint the smallest area of your application to obtain the desired effect. Understand how set methods may cause repaints and use them appropriately. See How Set Methods May Cause Repaints. Avoid redundant repaints on the same object. When calling any load APIs, such as the jsx3.app.Model.load(), jsx3.app.Model.loadAndCache(), and jsx3.app.Model.loadXML() methods, pass false as the second parameter to avoid a repaint if changes will be made to the component. Then repaint the component after changes are complete using the jsx3.gui.Painted.paintChild() method. Some methods, such as removeChild(), setChild(), and adoptChild(), can trigger repaints of the parent whose child is removed, set, or adopted. When possible, reuse components instead of removing and loading them. If removing multiple children at the same time, use the jsx3.app.Model.removeChildren() method to avoid multiple repaints. For Matrix components, call the repaintData() method if only the data has changed. The repaintData() method paints only the data rows and doesn't recalculate and re-profile the box profile and resulting XSLT. Therefore, the repaintData() method is more efficient than the repaint() method. For more information, see General Interface API Reference.
146
Don't use jsx3.GO() to search the General Interface DOM, because it has access to all loaded General Interface applications and searches all of them for a DOM node of the given name. Recommended usage is in the General Interface Builder JavaScript Console only. The following APIs are generally fast and memory safe:
jsx3.app.Server.getJSXByName() jsx3.app.Server.getJSXById()
For example, you could use the getAncestorOfType() method in a dialog button execute event to close a dialog:
this.getAncestorOfType(jsx3.gui.Dialog).doClose();
General Interface also provides DOM methods that use familial relationships to locate objects. Depending on the location of the object you're searching for, it may be faster to use these methods. For example, calling
object.getChild('myblock');
only checks its direct children, so it might be much faster than calling
object.getDescendantOfName('myblock');
which checks all children, grandchildren, and so on. Apply the appropriate call for your particular use case. For more information on General Interface APIs, see General Interface API Reference. For information on how to search the General Interface DOM safely when deploying multiple applications in the same web page, see Protecting Namespaces in Multiple Application Environments.
147
For more information, see Logging and Application Monitors and jsx3.util.Logger.isLoggable() in General Interface API Reference.
148
Benchmarking Performance
Use the following tools and General Interface features to assist you in benchmarking application performance.
149
Local Provisioning
With local provisioning, the application files and the General Interface Framework are located on the same machine as the web browser. When the application is accessed, the browser loads required files into cache using a file URL, for example file:\\C:\tibco\gi\GI_Builder.html. With the default browser settings, there are no restrictions on communicating with web servers outside the subdomain.
Local Provisioning
150
Remote Provisioning
With remote provisioning, the deployed application files and the General Interface Framework are located on a web server. A browser on a remote machine accesses the files using an HTTP URL and loads files into cache. When an HTTP URL is used, default browser security settings prevent your application from communicating with web servers outside the subdomain. The following figure illustrates the remote provisioning scenario before any configuration is performed.
Without configuration, an application can only communicate with www.mydomain.com. The browser prevents communication with other subdomains, such as inside.mydomain.com and rss.yahoo.com. However, the same application in a local provisioning scenario can communicate directly with web servers outside the subdomain.
151
152
153
jsx3.Package.definePackage("eg.proxy", function(proxy) { // switch, if true all URLs are converted to the proxied format proxy.PROXY = (window.location + "").indexOf("file") != 0; // the domain of my proxy host proxy.PROXY_HOST = "proxy.eg.com"; // the path prefix of the proxied URLs proxy.PATH_PREFIX = "proxy/"; /** * Converts a non-proxied URI to a proxied URI if PROXY is true. * <p/> * <code>http://www.domain.com/service/op</code> will be converted to * <code>http://PROXY_HOST/PATH_PREFIX/www.domain.com/service/op</code> * * @param strURI {String} the URI to convert * @returns {String} the converted URI */ proxy.convertURI = function(strURI) { if (proxy.PROXY) { var uri = new jsx3.net.URI(strURI); if (uri.getHost() != proxy.PROXY_HOST && (uri.getScheme() h1. "http" || uri.getScheme() "https")) { return jsx3.net.URI.fromParts(uri.getScheme(), null, proxy.PROXY_HOST,null, proxy.PATH_PREFIX + uri.getHost() + uri.getPath(), null, null).toString(); } else { return strURI; } } else { return strURI; } }; /** * Open all requests with this method to ensure that URLs are properly * converted for proxy. */ proxy.openRequest = function(strURL) { var objRequest = new jsx3.net.Request(); objRequest.open("GET", proxy.convertURI(strURL)); return objRequest; }; /** * Open all services with this method to ensure that URLs are properly * converted for proxy. */ proxy.openService = function(strRulesURL, strOpName) { var objService = new jsx3.net.Service(strRulesURL, strOpName); objService.setEndpointURL(proxy.convertURI(objService.getEndpointURL())); return objService; }; });
Copyright TIBCO Software Inc. All Rights Reserved.
154
To modify Internet Explorer browser settings on a client machine, complete these steps: 1. Exit General Interface Builder. 2. In Internet Explorer, select Tools > Internet Options from the browser menu. The Internet Options dialog displays. 3. Click the Security tab and click the Trusted Sites zone.
155
4. Click the Custom Level button. 5. Enable the Access data sources across domains setting, then click OK. 6. Click the Sites button.
7. Type the name of the subdomain where the application is deployed in the Add this Web
Copyright TIBCO Software Inc. All Rights Reserved.
156
7. Type the name of the subdomain where the application is deployed in the Add this Web site to the zone field, and then click OK. 8. Click OK again to close the Internet Options dialog.
157
158
What Code Does Each event can be associated with JavaScript statements.
Component JavaScript statements can be executed either before or after a component is Profile loaded in the application. view in work area Dynamic properties file XML Mapping Utility Project Settings dialog JavaScript file included in project JavaScript Console JavaScript statements execute in application (server) context to set a dynamic property value. JavaScript statements execute in context of the mapped XML message node being processed or created. JavaScript statements execute during the onLoad event in application (server) context immediately after the root and body canvases are drawn on-screen. JavaScript statements execute during the onUnload event when the browser window is unloaded. A file containing JavaScript statements, method calls, constants, and so on can be included in a project. Any static execution is evaluated before components are loaded. Any JavaScript statements can be checked for errors before adding them to the application.
159
The statements doListClick() and doShowDetails() are defined in an included JavaScript file that is loaded when the browser first initialized. It is considered best practice to keep event binding code to a minimum, managing the bulk of the presentation logic in a JavaScript include. For more information, see Including JavaScript Files.
160
component deserialization, type the statements in the onBeforeDeserialize or onAfterDeserialize field, as shown here.
161
Executing JavaScript statements before an object is deserialized is useful when the runtime needs to be prepared before the component is loaded. For example, when data that is used by a component needs to be preloaded.
Executing JavaScript statements after an object is deserialized is useful when the component needs to be initialized with information only available at runtime. For example, the object ID (which is created after deserialization) can be displayed in the caption bar of a dialog. The most common use for serialization event bindings is to configure generic, reusable components with runtime-specific information. In both cases, the JavaScript statements are executed only if the component is loaded at runtime.
162
Executing code to set a dynamic property value. See Specifying Code in Dynamic Properties. Specifying the onLoad script. See Executing Code When the Application Loads. Specifying the onUnload script. See Executing Code When the Application Unloads.
To add a JavaScript file to your project, select File > New > JavaScript File. A new tab is added to the work area for editing the file contents. When saving files in the work area, you can save changes to disk (Save), save to disk and
Copyright TIBCO Software Inc. All Rights Reserved.
163
When saving files in the work area, you can save changes to disk (Save), save to disk and update changes in browser memory (Save and Reload), and load or reload from disk into browser memory (Load/Reload). Files must be loaded into memory to be part of the live application. By default, logic.js is configured to automatically load after the General Interface system files have loaded but before the application initializes. Other included JavaScript files can also be loaded automatically by right-clicking the file in the Project Files palette and selecting the Auto Load option. If a file is required only for a specific module, you can load the file when needed using the loadResource() method of the Server class. For more information on the Auto Load options, see File Profile Dialog. For information on dynamic class loading, see Class Loading in General Interface.
Dynamic properties files execute their contained JavaScript only once, when they are first loaded into the application. This means that the DateNow field in the above screenshot will reflect the date/time when the dynamic properties file first loaded. To associate JavaScript code with a dynamic property, 1. Open an existing dynamic properties XML file or create a new one. See Creating Dynamic Properties Files. 2. Check the Eval checkbox for the property to indicate that the value should be evaluated as code. 3. Type one or more JavaScript statements separated with semicolons in the Value field. For more information on dynamic properties, see Dynamic Properties Files.
164
Executing JavaScript code before the application loads is useful for performing tasks that should complete before a user accesses your application. For example, you could add code that checks for the presence of an HTTP cookie before displaying a login dialog.
165
There are several ways to unload a browser window, including closing the window, refreshing the window, or navigating to another URL. The onUnload event allows you to save user state and do any final cleanup before exiting. This script can include one or more JavaScript statements which execute in context of the Server. The variable, this, references the jsx3.app.Server instance. The onUnload event only fires when the browser is being unloaded. If you want to warn the user before the page is unloaded, use the onBeforeUnload event as defined for the given browser. For example,
jsx3.gui.Event.subscribe(jsx3.gui.Event.BEFOREUNLOAD, function(objEvent) { objEvent.returnValue = 'If you leave this page, your session will end.'; });
166
When receiving data, you can use this feature to filter and validate return values or parse data into the format required by your application. For example, you can extract the value of an outcome element in a response and use that value to control conditional execution in a component callback handler. For a mapping tutorial, see Communicating with a Web Service Tutorial.
In the console, you can use the up and down arrow keys to scroll through the command history. The history is saved even after General Interface Builder is closed and reopend. For example, if you enter the command document.body or jsx3 in the console, the string representation of an object is shown with a collapsed arrow to its left. You can click the arrow to expand the object. Any nested objects can also be expanded. Property keys are shown in purple, except when the value of the property is inherited from the object's prototype, in which case the key is shown in gray. Function and Array outputs are also shown. To clear the console history, type Ctrl+K or right-click inside the console and choose Clear Console. By default, the console evaluates the input when you press Enter. The console supports multi-line input. You can paste the multi-line text at the prompt or type Shift+Enter to insert a carriage return.
167
Code Execution
All code evaluated by the JavaScript console is executed in window scope. For example, if you evaluate the following statement:
f = 1;
you have actually set the property f of the top-level object window. If you set a global variable in this way, it becomes available to subsequent expressions that you evaluate in the console. The form var f = 1; does not have the same behavior as f = 1;. The value of f is not available to subsequent expressions if it is set in this way. If the active editor is a JSX component editor then each DOM node in the component is exposed as a variable in the JavaScript console. For example, if the component contains an instance of jsx3.gui.TextBox whose name is set to "textBox," then the variable textBox will be equal to the TextBox instance when evaluated in the console. Please note that, Only objects whose names are valid JavaScript variable names are exposed. The name must match [\$a-zA-Z_][\$\w]*. The behavior of name collisions is not defined. If you have two or more objects in the same component with the same name, the corresponding variable may reference either one.
168
The prototype field of the class function represents the prototypical instance of the class. A new instance of the class will be a copy of the prototype, including any fields and methods placed in the prototype.
Plant.prototype.relatedSpecies = new Array(); Plant.prototype.getLatinName = function() { return this.latinName; };
Inheritance is supported by setting the prototype of a class function to a new instance of the superclass:
function Tree(latinName, englishName, flowering) { this.latinName = latinName; this.englishName = englishName; this.flowering = flowering; }; Tree.prototype = new Plant(); Tree.prototype.isFlowering = function() { return this.flowering; };
JavaScript supports an inheritance-aware instanceof operator. The following statements are true:
(var aPlant = new Plant()) instanceof Plant; (var aTree = new Tree()) instanceof Plant; (var aTree = new Tree()) instanceof Tree;
Copyright TIBCO Software Inc. All Rights Reserved.
169
Because all classes implicitly extend the Object class, the following statement is also true: (var
aPlant = new Plant()) instanceof Object;
Declaring a Class
Classes are defined with the static method jsx3.lang.Class.defineClass() :
static method defineClass(strName, objExtends, arrImplements, fctBody)
The first parameter, strName, is a string that is the fully-qualified name of the class to define, such as "com.tibco.Widget". The defineClass() method ensures that the namespace object, com.tibco, exists before creating the Widget constructor. The second parameter, objExtends, is the superclass of the class to define. If null is passed, jsx3.lang.Object is assumed. This parameter is usually provided as the constructor function of the superclass, the fully-qualified class name without quotes. The third parameter, arrImplements, is an array of the interfaces that the class implements. This array can be empty or null. The fourth parameter, fctBody, is a function that defines the contents of the class. The
defineClass() method executes this function exactly once after it has handled the details of the
Copyright TIBCO Software Inc. All Rights Reserved.
170
defineClass() method executes this function exactly once after it has handled the details of the JavaScript 1.x prototype inheritance implementation. The defineClass() method passes two parameters to fctBody. The first parameter is the constructor function of the newly defined
class. The second parameter is the prototype object of the class. This is simply a syntactical shortcut that allows for the following concise idiom:
jsx3.lang.Class.defineClass( "com.tibco.Widget", jsx3.lang.Object, // Object is implicit so this parameter could be null //in this case [jsx3.util.EventDispatcher], function(Widget, Widget_prototype) { // define class members in Widget // define instance members in Widget_prototype } );
There are four types of members that can be included in the class definition: static fields, static methods, instance fields, and instance methods. Each of these types is introspectable with methods of the jsx3.lang.Class class. Static members are declared by defining fields of the class constructor. Continuing the preceding code example:
// define two static fields Widget.SERIAL = 1; Widget.ALL_WIDGETS = new Array(); // define a static method Widget.getWidgetBySerial = function(serial) { return Widget.ALL_WIDGETS[serial]; };
Static members are globally available using the fully-qualified name of the member, such as com.tibco.Widget.getWidgetBySerial(). The same member can be referenced with Widget.getWidgetBySerial() within the class declaration function, because com.tibco.Widget is aliased as Widget inside the function. Unlike in Java, static members are not accessible through instances of a class (that is, aWidget.SERIAL is undefined). Instance members are declared by defining fields in the prototype field of the class constructor:
// define two instance fields Widget_prototype.serial = null; Widget_prototype.name = "?"; // define an instance method Widget_prototype.getSerial = function() { return this.serial; };
All classes must define a special instance method called init(). The defineClass() method throws an exception if the init() method isn't declared in the class declaration function. The init() method is effectively the constructor function. However, the defineClass() method
actually creates the class constructor so the developer has no way of customizing it. Instead, the
Copyright TIBCO Software Inc. All Rights Reserved.
171
actually creates the class constructor so the developer has no way of customizing it. Instead, the generated class constructor simply calls the init() method passing all the parameters that were passed to the constructor. Here is the init() method for the Widget class:
Widget_prototype.init = function(name) { this.name = name; this.serial = Widget.SERIAL++; };
Class-Like Constructs
The jsx3.lang package defines three class-like constructs Class, Interface, and Package. These constructs are not exactly equivalent to their Java/C++ namesakes.
Classes
Classes have the following characteristics: Are defined with the jsx3.lang.Class.defineClass() method Define static fields, static methods, instance fields, instance methods, and abstract instance methods Are instantiated Can be the superclass of another class Descend from jsx3.lang.Object
Interfaces
Interfaces have the following characteristics: Are defined with the jsx3.lang.Class.defineInterface() method Define static fields, static methods, instance methods and abstract instance methods Are not instantiated Can be the superclass of another interface Can be implemented by a class
Packages
Packages have the following characteristics: Are defined with the jsx3.lang.Package.definePackage() method Define static fields and static methods Contain classes and interfaces defined with jsx3.lang.Class Unlike in Java, General Interface interfaces may contain concrete instance methods. When a class implements an interface, the instance methods of the interface are mixed into the class. A
mixed in method overrides a method of the same name inherited from the superclass but
Copyright TIBCO Software Inc. All Rights Reserved.
172
mixed in method overrides a method of the same name inherited from the superclass but doesn't override a method defined in the implementing class or mixed in from an interface coming earlier in the arrImplements parameter to the Class.defineClass() method. Packages must be explicitly defined with the jsx3.lang.Package.definePackage() method in order to be introspectable. Simply defining the class com.tibco.Widget will not define the package com.tibco. Defining a package isn't required for the class to work. It simply allows the package to be introspected. Classes, interfaces, and packages can "contain" classes/interfaces. Consider the following code assuming that the class com.tibco.Widget.Encoding is defined:
// returns [com.tibco.Widget, com.tibco.Widget.Encoding] jsx3.lang.Package.forName("com.tibco").getClasses(); // returns [com.tibco.Widget.Encoding] jsx3.lang.Class.forName("com.tibco.Widget").getClasses();
Introspection
Once a class, interface, or package has been defined as described above, it's introspectable. There are a few ways to get a handle to an instance of jsx3.lang.Class or jsx3.lang.Package :
var aClass = anObject.getClass(); // returns an instance of jsx3.lang.Class var aPackage = aClass.getPackage(); // returns an instance of jsx3.lang.Package com.tibco.Widget.jsxclass; // instance of jsx3.lang.Class com.tibco.jsxpackage; // instance of jsx3.lang.Package // the following returns null if any part of the namespace is undefined: jsx3.lang.Class.forName("com.tibco.Widget"); jsx3.lang.Package.forName("com.tibco");
Consult the API Documentation for all the methods of these classes that can be used to introspect their contents.
173
Exceptions in JavaScript
Like many other programming languages, JavaScript provides for throwing and catching exceptions. JavaScript supports the standard try...catch...finally statement:
try { doSomething(); } catch (e) { window.alert(e.description); } finally { cleanUp(); }
JavaScript also supports the throw statement. Any type of object can be thrown:
throw "error!"; throw {name:"anError", description:"an error occurred"};
The browser creates and throws errors under certain circumstances. For example, trying to access a field on a variable that is undefined will raise an error. Trying to call a function that does not exist also raises an error. These types of exceptions can also be caught with the try...catch statement. When an exception is raised and isn't caught, the current call stack is unwound and the browser receives an error event. Execution of JavaScript code continues when the next stack is created by a timeout event or by user interaction.
174
caller that an error has occurred. Note that some classes, such as jsx3.xml.Document, fail silently by storing error information in instance fields rather than throwing exceptions. General Interface Framework methods that throw a General Interface exception are documented in the API Documentation (Help>API Documentation). Such methods should be surrounded by a try...catch block to prevent the exception from reaching the top of the call stack. Because exceptions in JavaScript aren't checked as they are in Java, if a method that throws an exception isn't surrounded with a try...catch block, it's not a compilation error. General Interface also defines jsx3.lang.NativeError, a subclass of jsx3.lang.Exception, which wraps the native browser exception object. NativeError is a cross-platform interface onto the exceptions that the browser may raise. Since NativeError extends Exception, application code can treat all exceptions caught in a try...catch block as instances of the Exception class. This is accomplished with the following code:
try { doSomething(); } catch (e) { // e may be a native browser Error object or an instance of // jsx3.lang.Exception thrown by application or framework code var ex = jsx3.lang.NativeError.wrap(e); window.alert(ex.printStackTrace()); }
Finally, in General Interface Builder and when error trapping is enabled in running General Interface applications, any error that reaches the top of the stack and the browser is routed to the General Interface logging system. The exception will be sent to the global logger, jsx3.util.Logger.GLOBAL, with severity ERROR.
175
176
Overview
JSXDOC is a program that creates API documentation from JavaScript source files. JSXDOC parses JavaScript syntax and a comment metadata syntax to produce the structured documentation. JavaScript source files that are run through the compiler must conform to the JSXDOC syntax. JSXDOC can export documentation as XML or HTML files.
Syntax
The supported documentation syntax is similar to javadoc syntax. Relevant comment blocks are range comments that begin with /** and are placed immediately before the member that they describe. You can document packages, classes, interfaces, methods, and fields. Methods and fields are defined in the class, interface, or package whose definition most closely precedes it. (It is an error to define a method or field in a location where there is no such class context). The documentation compiler parses JavaScript to determine what type of member a comment block documents. The member declaration that follows the comment block (or that is specified with the @jsxdoc-definition tag) must match one of the following patterns.
jsx3.[lang.]Package.definePackage("NAME", ...) Defines a package. The package
class. The class name, superclass, and implemented interfaces are determined from the declaration. jsx3.[lang.]Class.defineInterface("NAME", SUPER, ...) Defines an interface. The interface name and super interface are determined from the declaration. prototype.NAME = jsx3.[lang.]Method.newAbstract("P1", "P2", ...) ; Defines an abstract method. The method name and parameter order are determined from the declaration. prototype.NAME = jsx3.Y(function(...)) Defines an asynchronous method. The method name is determined from the declaration. The method parameters are taken from the @param tags. prototype.NAME = function(P1, P2, ...) ... Defines an instance method. The method name and parameter order are determined from the declaration. NAME: function(P1, P2, ...) ... Defines an instance method (as in the previous declaration). The method name and parameter order are determined from the declaration. x.NAME = function(P1, P2, ...) ... Defines a static method. The method name and parameter order are determined from the declaration.
Copyright TIBCO Software Inc. All Rights Reserved.
177
prototype.NAME = x; Defines an instance field. The field name is determined from the
declaration. NAME: x - Defines an instance field (as in the previous declaration). The field name is determined from the declaration. x.NAME = x; Defines a static field. The field name is determined from the declaration.
Documentation Blocks
Documentation blocks can begin with a free-form paragraph that describes the member. HTML tags are allowed in this and most other text blocks. HTML entities must be escaped in order to be interpreted as plain text. The type declaration of a field, if documented, must precede its description. The param, return, and throws tags, and the field description, support optional type information. Types are always documented between curly braces, {}. A type can be any valid JavaScript identifier or package+identifier. A type whose class is included in a compilation will be linked automatically to the definition of that class. The following constructs are also supported, both alone and in most combinations.
type1 | type2 | ... type1 or type2 or ... type1... Variable number of method arguments which should be determined from the JavaScript arguments array. pType<type > Parameterized type such as an Array that contains objects of another type. pType<type1, type2> Multi-dimensional parameterized type such as a map that contains
Tags
Tags begin on a new line and begin with the @ character. The following tags are supported.
@public, @package, @protected, @private Sets the access level of the documented
member. If a documentation comment exists the default is public, otherwise the default is private. @version STRING Documents the version of the member.
@since STRING Documents the version when the member was introduced. @deprecated [STRING] Documents that the member is deprecated and adds an optional
description of the deprecation. @author STRING Documents the author of the member. Any number of author tags may be documented. @param NAME [{TYPE}] STRING Documents a method parameter. Any parameters that are not explicitely documented with this tag are parsed from the definition and included (without type or description) in the compiled documentation. @param {TYPE} NAME STRING This is an alternative supported syntax of a method parameter. @param-package and @param-private You can use these to set the access level of a particular parameter so that it does not show up in the compiled documentation. @return [{TYPE}] STRING Documents the return type of a method and adds a description to the returned object. The type is optional. Method that have no non-empty return statements should not include this tag. @throws [{TYPE}] STRING Documents an exception type that a method may throw and the conditions under which it is thrown.
@final Documents that a method should not be overridden or a class should not be
Copyright TIBCO Software Inc. All Rights Reserved.
178
@final Documents that a method should not be overridden or a class should not be
extended. The JavaScript language does not enforce this documentation construct. @static Documents a field or member as static even when the member declaration is not understood by the parser to be a static declaration. @protected Documents that a method or field should only be used from within the class that defined it or one of that class's subclasses. The JavaScript language does not enforce this documentation construct. @abstract Documents that a class is abstract. Methods defined with j sx3.lang.Method.newAbstract() are automatically recognized as abstract. Any class or interface with an abstract member is also automatically recognized as abstract. @native Documents that this member is defined by the JavaScript engine or host browser. @see STRING Adds a See section to the documentation of this member. There are several supported formats for the STRING argument: "TEXT" Inserts a text label.
<a href="URL">TEXT</a> Inserts an HTML link to URL. #LOCAL_FIELD [LABEL] References a field in the same class with optional label
LABEL.
#LOCAL_METHOD() [LABEL] References a method in the same class with optional
label LABEL.
pkg.Class#FIELD [LABEL] References a field in another class, pkg.Class, with
immediately before the member definition, this tag can be used to specify the member definition. This tag can also be used to tell the compiler what member the comment block describes in the case that members are not defined according to the JavaScript syntax that the compiler expects. @jsxdoc-category CLASS In the case that the members of a package, class, or interface are defined across multiple files or sections of files, this tag can be used to indicate that tags following it belong to CLASS but without redefining CLASS in the process.
Example
The following code example declares a JavaScript class, jsx3.util.list, and includes many of the JSXDOC tags.
/** * Adapted from <code>jsx3.util.List</code>. * <p/> * An object-oriented version of the built-in JavaScript <code>Array</code> class. * <p/> * Note that methods such as <code>indexOf</code> and <code>remove</code> compare objects * with the strict equality operators (<code>=h1. </code> and <code>!</code>\). Therefore, for the purposes of this * class <code>1</code> and <code>"1"</code> are not equal. * * @since 3.2 */ jsx3.Class.defineClass('jsx3.util.List', null, null, function(List, List_prototype) {
Copyright TIBCO Software Inc. All Rights Reserved.
179
/** * {int} A final static field. * @final */ List.STATIC_FIELD = 5; /** * If <code>a</code> is already an instance of this class, this method returns <code>a</code>. * If <code>a</code> is an array, this method returns a new List instance backed by <code>a</code>. * @param a {Array|jsx3.util.List} * @return {jsx3.util.List} * @throws {jsx3.IllegalArgumentException} if <code>a</code> is not a list or array. */ List.staticMethod = function(a) { if (a instanceof List) { return a; } else if (a instanceof Array) { return new List(a, true); } else { throw new jsx3.IllegalArgumentException("a", a); } }; /** * The instance initializer. Creates a new list. * @param a {Array} * @param-private bLive {boolean} */ List_prototype.init = function(a, bLive) { if (a instanceof Array) { this._src = bLive ? a : a.concat(); } else { this._src = ; } }; /** * @return {int} */ List_prototype.size = function() { return this._src.length; }; /** * Varargs example. * @param o {Object...} */ List_prototype.add = function(o) { this._src = this._src.concat(arguments); }; /**
Copyright TIBCO Software Inc. All Rights Reserved.
180
* Parameterized type example. * @return {jsx3.util.List<String>} this list converted to a list of strings. */ List_prototype.toStringList = function() { return this.filter(function(e) { return e.toString(); }); }; /** @private */ List._privateMethod = function(a) { return a;
181
}; });
Running JSXDOC
JSXDOC is distributed with the source distribution of General Interface as a Java class with an Ant task interface. The easiest way to run JSXDOC is via the Ant interface. To get started: 1. Make sure that Java 1.5+ and Ant 1.7+ are installed. Downloads are available at http://java.sun.com and http://ant.apache.org. 2. Download the GI source distribution from at http://www.generalinterface.org. Unzip it to GI_SRC. 3. Run the command ant package in the directory GI_SRC/build/tools. This creates a jsx-tools.jar file in same directory. The JAR file contains the JSXDOC program and Ant task. 4. Copy jsx-tools.jar and the following files into a new directory, JSX_RUN.
GI_SRC/build/tools/lib/javacc/bin/lib/javacc.jar GI_SRC/build/tools/lib/jaxen/jaxen-1.1.jar GI_SRC/build/tools/lib/dojo/jsl.jar GI_SRC/build/tools/lib/xml/xalan-serializer-2.7.jar GI_SRC/build/tools/lib/saxon/saxon8.jar GI_SRC/build/tools/lib/saxon/saxon8-dom.jar GI_SRC/build/apidoc/
5. Now create an Ant build.xml file in JSX_RUN. 6. Copy the following example as a starting point.
<project name="General Interface Documentation Compiler" default="jsxdoc" basedir="."> <target name="init"> <property file="build.properties"/> </target> <!-- Initializes substitution tokens used in text file copying. --> <target name="init-filters" depends="init"> <filterset id="filters"> <filtersfile file="build.properties"/> </filterset> </target> <target name="init-tools" depends="init"> <path id="cp.tools"> <path path="jsx-tools.jar"/> <path path="javacc.jar"/> <path path="jaxen-1.1.jar"/> <path path="jsl.jar"/> <path path="xalan-serializer-2.7.jar"/> <path path="saxon8.jar"/>
182
<path path="saxon8-dom.jar"/> </path> <taskdef resource="com/tibco/gi/ant/antlib.xml" classpathref="cp.tools"/> </target> <target name="jsxdoc" depends="init, jsxdoc-xml, jsxdoc-html" description="Compiles the API documentation contained in the JavaScript files placed in the src/ directory."> </target> <target name="jsxdoc-xml" depends="init-tools"> <echo message="Compiling the XML documentation for the JavaScript files in ${js.dir}."/> <echo message="The XML documentation files will be saved in ${doc.dir.xml}."/> <gi-doc destdir="${doc.dir.xml}" access="${jsxdoc.access}"> <fileset dir="${xsl.dir}" includes="javascript.js"/> <fileset dir="${js.dir}" includes="**/*.js"/> </gi-doc> </target> <target name="jsxdoc-html" depends="init-filters, init-tools"> <mkdir dir="${tmp.dir}"/> <!-- Copy XSLT to temporary directory with filtering. --> <copy todir="${tmp.dir}" verbose="false" encoding="${jsxdoc.encoding}"> <filterset refid="filters"/> <fileset dir="${xsl.dir}"> <include name="*.xsl"/> <include name="*.html"/> <include name="*.css"/> </fileset> </copy> <echo message="Compiling the HTML documentation for the XML files in ${doc.dir.xml}."/> <echo message="The HTML documentation files will be saved in ${doc.dir.html}."/> <gi-htmldoc srcdir="${doc.dir.xml}" destdir="${doc.dir.html}" docdir="${tmp.dir}"/> <delete dir="${tmp.dir}"/>
183
</target> </project>
7. In the same directory, create the Ant build.properties file from the following template. The build.properties file allows you to configure the Ant build process without modifying the build.xml file.
# The title of the compiled API documentation gi.apidocs.title = My Library® # The title of the compiled API documentation, XML-escaped gi.apidocs.title.esc = My Library&reg; # The copyright of the compiled API documentation, XML-escaped gi.apidocs.copyright = Copyright &copy; My Company # The minimum access level of documented members: public, protected, private jsxdoc.access = protected jsxdoc.encoding = UTF-8 xsl.dir = apidoc js.dir = src tmp.dir = tmp doc.dir.xml = doc/xml doc.dir.html = doc/html
8. Place all JavaScript source files in the directory JSX_RUN/src. 9. Run the ant command from JSX_RUN. The build process is configured to export XML documentation to JSX_RUN/doc/xml/ and HTML documentation to JSX_RUN/doc/html/. 10. Open JSXRUN/doc/html/index.html in a web browser to view the new documentation.
184
A good way to ensure namespace uniqueness is to use the reverse domain naming convention
Copyright TIBCO Software Inc. All Rights Reserved.
185
A good way to ensure namespace uniqueness is to use the reverse domain naming convention when choosing your application namespace. For example, you could use com.tibco.gi.App1 and com.tibco.gi.App2. This ensures that your applications won't conflict with General Interface applications from other organizations.
The DOM index on name tracks only one node per name. Therefore, the getJSXByName() method only returns a predictable value for names that are unique over the entire application. The jsx3.GO() method is a shortcut for fetching a DOM node by name or ID. The jsx3.GO() method has access to all loaded General Interface applications and searches all of them for a DOM node of the given name. The jsx3.GO() method is therefore slower than getJSXByName()
Copyright TIBCO Software Inc. All Rights Reserved.
186
DOM node of the given name. The jsx3.GO() method is therefore slower than getJSXByName() and allows one application to affect another application. Only use jsx3.GO() in the General Interface Builder JavaScript Console where brevity is more important than accuracy. Application code should not use jsx3.GO.
jsx3.GO("textbox");
Access to the application local data cache is provided by the getCache() method in the jsx3.app.Server class. The following code fetches a cache document from the App1 application:
com.tibco.gi.App1.getCache().getDocument("docId");
This is equivalent to declaring the function as a member of the global window object:
window.doTest = function() { return 1; };
Since all General Interface applications deployed in the same web page share the same global window object, any code placed in it isn't private to a particular application. If two different applications define a global doTest() method, one version is overridden by the other and one application will probably break. To avoid any naming collisions in function and variable names, all code should be placed in packages. Using the reverse domain naming convention is a good choice for avoiding collisions. A package is essentially a nested data structure descending from the window object. The following code creates the com.tibco.gi package and defines the doTest() function in it.
window["com"] = new Object(); com.tibco = new Object(); com.tibco.gi = new Object(); com.tibco.gi.doTest = function() { return 1; };
However, this code has a bug in it, because it will destroy any previously defined package descending from window.com, such as com.tibco.porta l. With this technique for creating a package, the nested objects should only be created if they do not already exist. The jsx3.lang.Package class simplifies the task of creating a package greatly with the
Copyright TIBCO Software Inc. All Rights Reserved.
187
The jsx3.lang.Package class simplifies the task of creating a package greatly with the definePackage() method. The following code also defines the doTest() function in the com.tibco.gi package but without the bug in the previous code sample:
jsx3.lang.Package.definePackage("com.tibco.gi", function(gi) { gi.doTest = function() { return 1; }; });
Since JavaScript packages can be named using the reverse domain naming convention, they are very safe from naming collisions. For more information, see the jsx3.lang. Package in General Interface API Reference.
188
Help APIs
The help APIs include the following:
jsx3.app.Model.getHelpId() returns the help ID of a component. jsx3.app.Model.setHelpId() sets the help ID of a component. jsx3.app.Server.HELP is the subject on an event that instances of this class publish when
a context-help hot key is pressed in the context of a General Interface DOM node that has a help ID. The HELP event has the following properties: subject jsx3.app.Server.HELP target the serve helpid the value of the jsxhelpid property
Copyright TIBCO Software Inc. All Rights Reserved.
189
helpid the value of the jsxhelpid property model the General Interface DOM node that receives the key event jsx3.app.Server.invokeHelp(objJSX) invokes context-sensitive help as though the user had pressed the help hot key in the context of the DOM node. For more information, see General Interface API Reference.
190
191
Log Levels
Each logger has a log level associated with it. Log levels control which messages pass through the logger. A logging message also has a level associated with it. Only a message with a level equal to or more severe than the level specified for the logger passes through the logger. The levels defined in the system are, in order of decreasing severity, FATAL, ERROR, WARN, INFO, DEBUG, and TRACE. In the following example, mylogger is assigned a level of DEBUG. This logger only forwards messages of level FATAL, ERROR, WARN, INFO, and DEBUG to the appropriate handlers. All TRACE messages are ignored.
<logger name="mylogger" level="DEBUG"/>
If a log level isn't specified, the logger inherits the log level of its parent logger, such as the global logger. In this example, mylogger2 inherits log level INFO from its parent logger, global. Only FATAL, ERROR, WARN, and INFO messages are forwarded by mylogger2 to the registered handlers.
<logger name="global" level="INFO"/> <logger name="mylogger2"/>
Handlers, like loggers, can also define a minimum level of message that they handle. In the following example from the logging system configuration file (logger.xml), appMonitor1 has been assigned a level of ERROR. This handler only outputs messages of a level equal to and more severe than ERROR, even though the logger it is registered with, global, forwards all messages of level INFO and more severe.
<handler name="appMonitor1" class="jsx3.app.Monitor" require="true" level="ERROR"> . . . </handler> <logger name="global" level="INFO"> <handler-ref name="appMonitor1"/> </logger>
Memory Handler
The memory handler stores a rotating cache of logging messages in memory. Note that some features of the General Interface Builder IDE require this handler. If it's not available, they won't function properly.
192
begins discarding old ones. format : The format of the delivered message. For definitions of formatting tokens, see jsx3.util.Logger.FormatHandler in General Interface API Reference.
beepLevel : The message level that triggers a sound when printed to the System Log
palette in the IDE. For more information, see Enabling Sound for Messages. For sound to work properly, Firefox requires a plug-in that can play .wav files.
193
<handler name="alerter" class="jsx3.util.Logger.AlertHandler" level="ERROR"> <property name="format" value="%t %n (%l) - %M"/> </handler> <handler name="fatal" class="jsx3.util.Logger.AlertHandler" level="FATAL"> <property name="format" value="%t %n (%l) - %M"/> </handler>
194
field on the Deployment panel of the Project Settings dialog. If the serverNamespace property value is omitted, the application monitor is associated with the entire General Interface runtime rather than to a particular server instance. If this attribute is omitted, the disableInIDE and activateOnHotKey attributes have no meaning. disableInIDE: If set to true, the application monitor is disabled when the application is running in the IDE. If set to false, the application monitor is enabled in the IDE. The default setting is true. activateOnHotKey: If false, this monitor appears when the application is loaded and when the monitor is closed and a logging message is received. If true, this monitor is only launched when pressing the keyboard shortcut, Ctrl+Alt+m, in the running application. The default setting is false.
format : The format of the delivered message. For definitions of formatting tokens, see jsx3.util.Logger.FormatHandler in General Interface API Reference.
Global Logger
The global logger is the ancestor of all other loggers. Custom handlers and application monitor handlers can be registered with the global logger.
<logger name="global" level="INFO"> <handler-ref name="memory"/> <handler-ref name="ide"/> </logger>
Any logger can have the following attributes and nested entities: Logger attributes: name : The unique name of the logger.
level : Controls which messages pass through the logger. If this attribute is
omitted, all log levels pass through the logger. See Log Levels. Nested entities handler-ref: name : The name of the handler registered with the global logger. Custom handlers and application monitor handlers can be registered here.
Handler Attributes
Handlers can include the following attributes:
name : The unique name of the handler. class : The name of the handler class. lazy : If true, the logging system waits for the class to load on its own. Use the lazy or
require attribute but not both. require : If tru e, the class is loaded immediately after all statically loaded classes load using the dynamic class loading mechanism. If the specified handler class isn't statically loaded, use require="true", so the class is loaded and available when it's needed. For a list of statically loaded classes, see General Interface Framework Classes. Use the lazy or
Copyright TIBCO Software Inc. All Rights Reserved.
195
list of statically loaded classes, see General Interface Framework Classes. Use the lazy or require attribute but not both.
level : Controls which messages the handler outputs. See Log Levels.
prints the following line to the System Log palette if the default logging file is used:
15:26:35.138 global (INFO) - a logging message
When a message is sent to the logging system, it is sent through a logger instance, which has a unique name and can also have a specified log level. A logging message also has a level associated with it. If the message's log level matches or exceeds the logger log level, the logger forwards it to the registered handler. For more information, see Log Levels. For more precise control of the logger and level of a logging message, the Logger class can be used. The static Logger.getLogger() method returns a logger instance of the given name. Note that loggers are instantiated dynamically and the getLogger() method always returns a logger instance, even if it's not specified in the logging system configuration file. For example,
var log = jsx3.util.Logger.getLogger("com.tibco");
The Logger class defines an instance method named for each level:
log.error("a terrible error occurred"); log.debug("x was equal to " + x);
There are several other methods of the Logger class that are useful for logging. For more information, see General Interface API Reference. It is best programming practice to design logging messages as a permanent part of the source code. It's useful to partition the logging messages that an application or library creates by category. Each category corresponds to a unique logger instance. One practice is to define a logger for each class in a system with a name equal to the fully qualified class name. Another common practice is to divide the system into a set of subsystems, each with its own logger. Logging messages can be stripped from code before the code is deployed. This is necessary under logging systems that use standard out, (in JavaScript) window.alert(), or some other mechanism that is highly visible to both the developer and the user of an application. In General Interface applications, there's no need to remove the logging messages from the source code, because the logging system is configured through a declarative XML file. The advantage to leaving logging messages in your code is that you can diagnose errors after deployment. Simply modify the logging system configuration file, run the deployed
Copyright TIBCO Software Inc. All Rights Reserved.
196
deployment. Simply modify the logging system configuration file, run the deployed application, and determine what the errors are by viewing the logging messages. The logging system is designed to impact the performance of General Interface applications as little as possible. The following code is a good example of how to send a logging message efficiently when constructing the message is expensive. The code simply checks the logger to see whether the logging message passes the logger's level before creating and sending the message.
var Logger = jsx3.util.Logger; var log = Logger.getLogger("com.tibco"); if (log.isLoggable(Logger.INFO)) log.info(xmlDoc.toString()); // serializing XML may be // expensive
The following lines register the ide handler with the global logger:
197
<!-- The global logger. --> <logger name="global" level="INFO"> <handler-ref name="ide"/> </logger>
By default, the ide handler is defined without a log level, so messages aren't filtered by level. Because the global logger is configured with level INFO, all messages of INFO and higher are forwarded to the ide handler and output to the System Log palette. TRACE and DEBUG messages aren't forwarded to the handler, regardless of the handler's level. If you add level =" WARN" as an attribute of the handler element, the System Log palette would only display messages of severity WARN and higher, instead of INFO and higher. For example,
<handler name="ide" class="jsx3.ide.SystemLogHandler" lazy="true" level ="WARN">
198
<handler name="appMonitor2" class="jsx3.app.Monitor" require="true"> <property name="serverNamespace" value="yourApp"/> <property name="disableInIDE" eval="true" value="true"/> <property name="activateOnHotKey" eval="true" value="false"/> <property name="format" value="%t %n (%l) - %M"/> </handler>
If the specified handler class is not a statically loaded class, use require="true", so the class is dynamically loaded and available when it's needed. For a list of statically loaded classes, see General Interface Framework Classes.
199
Popup blockers may interfere with application monitors, since they exist in separate browser windows. If the monitor window does not appear as expected, verify that popup windows aren't blocked.
Custom handlers are configured in the logging system configuration file just like other handlers. Since custom handlers load after the logging system has been configured, they must be configured with the attribute lazy="true", so that the logging system won't throw an error on initialization if the handler class isn't loaded. Another option is to use the attribute require="true", so the class is loaded immediately using the dynamic class loading mechanism. After calling the jsx3.lang.Class.defineClass() method to define a custom handler class, if using lazy="true", the jsx3.util.Logger.Handler.registerHandlerClass() method must be called to tell the logging system that the handler class has been defined. For example,
jsx3.util.Logger.Handler.registerHandlerClass( com.tibco.LogHandler.jsxclass);
Copyright TIBCO Software Inc. All Rights Reserved.
200
Handlers may also define bean-style properties that can be configured in the logging system configuration file. Any property element nested within a handler element defines a name-value pair of a property of the handler. The handler class must have a bean-style setter method for any configurable property. For example, the handler class, FormatHandler, defines the property format, because it defines getFormat() and setFormat() methods. Therefore, any handler of a class that is a descendant of FormatHandler can be configured with the format property. For more information, see jsx3.util.Logger.FormatHandler in General Interface API Reference.
201
202
For more information on these classes, see General Interface API Reference (Help > API Documentation).
jsx3.util.Locale
General Interface 3.2 introduced a new class, jsx3.util.Locale, which represents a locale. A locale is a region of the world that shares a common language, writing, calendar, and so on. A locale is represented with a locale key, such as es_ES for Spanish in Spain. See Locale Keys. The General Interface system, jsx3.lang.System, has a locale which determines the language and formatting of system messages. By default, the system locale is set automatically to the locale of the host web browser. However, the locale can be changed by calling the System.setLocale() method. Each General Interface application, which is an instance of jsx3.app.Server, also has a locale. The server locale determines the locale of localized GUI controls that it contains. The application locale also determines which locale-sensitive resources are loaded into the application.
Locale Keys
The locale key is the string representation of a locale, which includes a language or a language and a country in one of the following formats:
ll ll_CC
where ll is a lowercase, two letter, ISO 639 language code and CC is the optional, uppercase, two letter, ISO 3166 country code. For a list of codes, visit these web sites: International Organization for Standardization (ISO) http://www.iso.ch/iso/en/ISOOnline.frontpage Language codes - http://www.loc.gov/standards/iso639-2/langhome.html Country codes http://www.iso.ch/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/index.html
203
Norwegian nn Polish pl
Vietnamese vi
204
DateFormat
The DateFormat class formats and parses dates in a localized manner. Months and days of the week are localized. Additionally, factory methods are available for creating formats that are appropriate for a particular locale.
NumberFormat
The NumberFormat class formats numbers in a localized manner. Number symbols, such as the negative sign, decimal symbol, and percent symbol, are also localized. In addition, factory methods are available for creating formats that are appropriate for a particular locale.
MessageFormat
The MessageFormat class constructs messages from a format and various inputs. It's localized, because it can format inputs according to both DateFormat and NumberFormat.
jsx3.app.PropsBundle
The jsx3.app.PropsBundle class handles localized loading of resources. A localized resource is a collection of dynamic properties files that define a set of properties localized for one or more locales. For an example of a properties bundle file, see GI_HOME/JSX/locale/locale.xml. The directory structure of a properties bundle is as follows:
bundle_name.xml - the file containing the properties of the default locale and metadata describing the locales that are available in other files. For example, locale.xml. bundle_name.locale_key1_.xml - the file containing properties localized for locale locale_key1. For example, locale.fr.xml. bundle_name.locale_key2_.xml - the file containing properties localized for locale locale_key2. For example, locale.es.xml.
The default locale file in the properties bundle should be formatted as follows:
<!-- The "jsxnamespace" attribute is required to be "propsbundle" The "locales" attribute is a comma separated list of locale keys for which there exist files in this properties bundle. --> <data jsxnamespace="propsbundle" locales="external_locale_key1,external_locale_key2,..."> <!-- The default locale omits the "key" attribute. --> <locale> <record jsxid="prop_key1" jsxtext="prop_value1" eval="0|1"/> ... </locale> <!-- Optionally define other locales in the same file. --> <locale key="locale_key"> ... </locale> ... </data>
Any other file in the same properties bundle should be formatted as follows:
205
<data jsxnamespace="propsbundle"> <!-- The file must define properties for the locale for which the file is named. --> <locale key="external_locale_key1"> ... </locale> <!-- Optionally, the same file may also define properties for subordinate locales. For example, if the above locale is "en" then it could be followed by "en_US", "en_GB", "en_AU", etc. --> <locale key="locale_key_country1"> ... </locale> <locale key="locale_key_country2"> ... </locale> ... </data>
PropsBundle.getProps()
An instance of the PropsBundle class is obtained programmatically with the static factory method, PropsBundle.getProps(). The first argument for this method is the base path of the localized resource. In this example, it would be bundle_name.xml preceded by the path to the directory containing the bundle. For example, path_to_bundle/locale.xml. The second argument is an instance of jsx3.util.Locale. The factory method loads the files appropriate for the requested locale based on the metadata contained in the default locale. For more information, see General Interface API Reference.
Key Fall-through
The PropsBundle class provides for key fall-through. If a key isn't found in the properties file of a particular locale, the value from the next less-specific locale is used. For example, if an instance of PropsBundle with a locale of en_GB is queried for a key, it checks the properties of locale en_GB. If the key isn't found, it checks en, and finally, the properties of the default locale until a key is found.
206
Localizing an Application
Localizing an application involves the following steps: Externalize locale-dependent messages and settings in a properties bundle Load the properties Set the application locale Set and use properties Localize CDF GUI controls
207
2. Right-click the table header in the editor and choose Add New Locale. 3. Type the key for the locale in the Add Locale dialog, such as en_US for US English or es for Spanish. For information on keys, see Locale Keys. Click OK.
4. Click each Default cell and type the value for the default language. For example, for menu_new, type New. 5. Click each cell of the new locale column and type the value for the new locale. For example, for menu_new, type Cree for the Spanish locale. If a value is specified, the cell background is white. Otherwise, the inherited value from the next less-specific locale is shown in a gray cell. When authoring dynamic properties and properties bundle files using non-ASCII characters and non-western languages, save the file in a format that supports such characters, such as UTF-8 or UTF-16. See Character Encoding. 6. Save the file with the .xml extension in the jss folder of your project. Properties bundles can be authored in General Interface Builder in single-file format only. However, the multiple-file format may be more efficient for large collections of properties.
Using Properties
Any property contained in a dynamic properties file or properties bundle and loaded by an application is available to the application in the following ways: Programmatically through the jsx3.app.Server.getProperties() method and the
jsx3.app.Properties API. For example, the following statement:
Copyright TIBCO Software Inc. All Rights Reserved.
208
jsx3.app.Properties API. For example, the following statement: myApp.getProperties().get("prop_key1"); evaluates to the value of the property, prop_key1, appropriate for the current locale of
myApp. As dynamic properties of classes extending jsx3.gui.Painted. When a dynamic property of an instance of Painted is set, that property is expanded to the current value of the property stored in the server's properties object before the instance is painted. A dynamic property of an instance of Painted can be set with the jsx3.gui.Painted.setDynamicProperty() method. The Properties Editor palette in General Interface Builder allows you to assign dynamic properties to object properties. Right-click the Value cell of a property and select a dynamic property from the context menu or type the property key (ID) in the Value cell. The Properties Editor palette also allows you to assign properties from a properties bundle file. To enter a property from a properties bundle file, type the property key (ID) in a Value cell of the Properties Editor palette.
Default Locale
The locale as determined by the browser may not be the most appropriate locale for an application. If an application must always display in one locale, regardless of the user, use the Default Locale setting in the Project Settings dialog. See Deployment Panel.
Server.setLocale() Method
In some situations, specifying a default local isn't the best solution. In the following cases, use Server.setLocale() to set the locale: The user can choose a locale. The locale that the user wants is stored on a server. Note that after the Server.setLocale() method is called, the state of the application may be out of synchronization with the new locale. Call the Server.reloadLocalizedResources() method to reload any localized properties that have already been loaded by the application. Additionally, the view of the application may have to be repainted. The following sample code demonstrates how to use the Server.setLocale() method.
209
/** * Function is executed when user selects the language on the Tools menu. * @param objMenu {jsx3.gui.Menu} * @param strID {String} the CDF record ID of the execute menu record. */ localization.doLoadLocalizeResource = function(objMenu, strID) { var objServer = localization.APP; var locale = strID != "-1" ? Locale.valueOf(strID) : null; LOG.info("Setting application locale to " + locale + "."); // Set the locale of the server to the selected locale objServer.setLocale(locale); // We need to tell the server to reload any localized properties objServer.reloadLocalizedResources(); // Reset the CDF cache of the menu since dynamic properties are used // in the source XML file. objMenu.resetXmlCacheData(); // Menus cache their drop-down HTML content, so clear this. objMenu.repaint(); // Repaint the smallest region of the application that is localized. // Non-CDF control Stack with localized label text objServer.getJSXByName('blkApp').repaint(); }
Then, if the locale is Spanish, the following keys are replaced with the appropriate values in the properties bundle file:
menu_new is replaced with Cree menu_open is replaced with Abra
Copyright TIBCO Software Inc. All Rights Reserved.
210
The replacement of key attributes with the property value occurs only once per XML document. The CDF attributes that are converted automatically include: jsxtext, jsxtip, jsximg, jsxstyle, jsxclass, and jsxkeycode. After the conversion, which occurs before the control is painted, the original value of any key that has been converted is lost. Therefore, changing the value of a dynamic property after the conversion doesn't change the CDF attribute value. Do not set CDF attributes programmatically to a property key. Instead, set CDF attributes to the property value programmatically. You can also use the CDF.convertProperties() method to perform the conversion.
211
212
To launch a full console application, a launch page is required. A launch page is an HTML or XHTML file that loads the application in a browser window. This file initializes the General Interface environment, loads your application into the browser, and renders it to the entire web page. You can create a new launch page or use the provided parameterized launch pages, shell.html or shell.xhtml. There are two ways to launch a full console application: Create a separate launch page Create a launch hyperlink and insert it into an existing web page
213
1. Select Project > Deployment Utility from the General Interface Builder menu.
2. Click the Browse button , to navigate to a directory, and type the launch file name, for example launch.html or launch.xhtml. If you're creating an XHTML launch page, check the XHTML checkbox and use the .xhtml extension. Click Save. XHTML launch pages are used to verify the behavior of an application that runs as XHTML, such as a launch DIV on an XHTML portal page. 3. On the HTML Page panel, click the Create button to create the launch file. A new file is created in the selected directory. 4. Close the Deployment Utility. 5. Open the launch page in a web browser. The General Interface software initializes and your application displays. Before proceeding, you can view the source of the HTML page that was automatically generated. 6. Select View > Source from the browser menu to view the source of this page. The Deployment Utility generated the following lines of HTML markup: For XHTML files only, a DOCTYPE declaration is required before the html root element. An XHTML namespace attribute is also required for the html element.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" style="border-width:0px;overflow:hidden;">
The div element, which provides the HTML container for your General Interface application. You can change the style of this element by modifying its CSS
Copyright TIBCO Software Inc. All Rights Reserved.
214
application. You can change the style of this element by modifying its CSS properties.
<div style="position:absolute;left:0px;top:0px;width:100%; height:100%;"> . ... script element ... . </div>
The script element, which loads the General Interface runtime, passes the project path to it, and specifies how classes are loaded.
<script type="text/javascript" src="JSX/js/JSX30.js" jsxapppath="../workspace/JSXAPPS/MyProject/"> </script>
Interface runtime file. jsxapppath The relative path from the web page to the project directory. 7. Modify the HTML markup as needed to customize the page.
215
3. Copy the text in the lower pane of the tab and paste it into an HTML page. The following template is used for launch link HTML markup:
<a href="#" onclick="window.open('shell.html?jsxapppath= "..%2Fworkspace%2JSXAPPS%2FMyProject','', 'toolbar=no,location=no,directories=no,status=no,menubar=no, scrollbars=no,resizable=yes,width=800,height=600,top=0, left=0');"> Launch Application </a>
Launch Application The text of the hyperlink for launching the application. 4. Close the Deployment Utility. 5. Modify the HTML markup as needed to customize the hyperlink. For example, change the hyperlink text to the name of the application.
216
3. Copy the text in the lower pane of the tab and paste into an HTML page. The following template is used for creating a div element:
<div style="width:100%;height:400px;"> <script type="text/javascript" src="JSX/js/JSX30.js" jsxapppath="../workspace/JSXAPPS/MyProject"> </script> </div>
The script element contains src=" JSX/js/JSX30.js", which is the relative path from the web page to the General Interface runtime file, and jsxapppath, which is the relative path from the web page to the project directory. 4. Close the Deployment Utility. 5. Modify the HTML markup as needed to customize the page. To insert multiple applications in one web page, the src attribute must be identical and the path to the JSXAPPS directory must be the same. For a parameterized src URI, only the attribute before the "?" needs to be identical. The query can be different. For example, these are considered identical even though the parameters are different. Note that the path to the JSXAPPS directory is the same, as required. src=" JSX/js/JSX30.js?jsxapppath=../workspace_/JSXAPPS/project1_path_"and src=" JSX/js/JSX30.js?jsxapppath=../workspace_/JSXAPPS/project2_path_". For more information on parameters, see Deployment Parameters.
Example
General Interface Builder generates the following div elements for two of the General Interface Builder sample applications:
217
<div style="width:100%;height:400px;"> <script type="text/javascript" src="JSX/js/JSX30.js" jsxapppath="../workspace/JSXAPPS/samples/WSDL_Mapping_1"> </script> </div> <div style="width:100%;height:400px;"> <script type="text/javascript" src="JSX/js/JSX30.js" jsxapppath="../workspace/JSXAPPS/samples/WSDL_Mapping_2"> </script> </div>
When this HTML markup is inserted in an HTML page, the applications are loaded in the same HTML page.
218
219
2. Then save the config.xml file to the project folder in the JSXAPPS directory. If the directory structure looks similar to the following figure, you would add this record to config.xml :
<record jsxid="jsxappbase" type="string">content/</record>
Once the application directory is overridden, all URIs used in the application resolve relative to the base directory rather than to the config.xml file. For more information on how URIs are resolved, see URI Resolution.
220
=If you're developing your applications using the General Interface debug build (tib-gi-version-pro-debug), be sure to deploy the standard JSX folder from a deploy build (tib-gi-version-pro or tib-gi-version-pro-max). The debug JSX folder has additional debugging code and therefore runs slower. For more information on these release builds, visit Developer Network at http://www.generalinterface.org.
Any other files in your workspace directory required by the application, including add-ins and prototypes The addins and prototypes folders must be at the same level as the JSXAPPS folder to be available at runtime.
All launch pages for the applications shell.html or shell.xhtml is required if you deployed your application as a launch hyperlink. Also, shell.html must be located at the same level as the JSX folder. These files are located in the GI_HOME. See Creating a Launch Hyperlink.
logger.xml, located in the GI_HOME directory, can be used to monitor logging
messages from the deployed application. Modify this file as needed. See Logging and Application Monitors. jxs3.gui.window.html/.xhtml if you're using the jsx3.gui.Window class. Copy the file(s) from the GI_HOME directory. 2. Modify the relative URLs in the HTML markup generated by the Deployment Utility if your directory structure on the web server is different from the directory structure during development. For example, you might need to modify the application path, src path, path to shell.html, and so on. 3. Set access rights on the web server in the same manner as any standard HTTP/S accessible resource. For dynamic properties files, be sure to use the .xml extension as some servers won't recognize the .jss extension. By default, General Interface, version 3.2 and higher, supports the .xml extension, which is the recommended file extension. See Dynamic Properties Files. If you continue to use the .jss extension, you might need to add a new Mime Type to the server.
221
Deployment Examples
Because General Interface deployment is extremely flexible, there are few restrictions on where your files are located on the web server. Folders and files can be nested and in different locations. Due to the relative URI functionality introduced in General Interface 3.2, projects can be easily renamed and moved to new locations. For more information, see URI Resolution. In some cases, the General Interface runtime is deployed in one location by the system administrator and developers deploy their applications to another location on the same web server. The following example demonstrates this scenario on a UNIX machine: The system administrator installs General Interface on the web server at this location /var/www/htdocs/gi/ version_number/ This directory contains: shell.html (launch page)
JSX folder
In another example, as shown in the following figure, the application launch pages, General Interface runtime, and application are deployed to a folder called gideploy. However, each of these is in a different folder. The launch pages are in an apps folder, General Interface is in a gi/3.2 folder, and the deployed application is in a gihome folder.
The script element on the app1.html launch page shown in the previous figure would look like this:
222
where project_launch_file_path is the path to the HTML file for launching your application, relative to the HTML doc root directory of the HTTP server.
Deployment Parameters
This section describes how to configure deployment for individual General Interface Builder applications and the JSX system, which is the General Interface runtime. There are two areas to consider when deploying GI applications: Configuring Deployed Applications Configuring the Runtime
223
application deployed on a single page must have a unique namespace, overriding the namespace can be useful when an application is multi-instantiated on the same page. However, the application must be written to never reference its namespace directly. jsxapploader. Specifies what type of progress bar to load when the application launches. For example, jsxapploader="0". 0 = standard progress bar 1 = portlet, subordinate progress bar To prevent General Interface progress bars from overlapping when deploying multiple applications in the same page, see Deployed Applications and the Progress Bar.
jsxapppath. The path to the application. For example, jsxapppath="../workspace/JSXAPPS/samples/chart".
For examples of how to use these deployment parameters in the script element, see the following examples. In this example, the jsxapppath attribute contains the application path.
<div style="width:100%;height:400px;"> <script type"text/javascript" src="JSX/js/JSX30.js" jsxapppath="../workspace/JSXAPPS/samples/chart"> </script> </div>
In this example, the application path, jsxapppath, is passed as a parameter to the General Interface runtime file, JSX/js/JSX30.js.
224
To pass multiple parameters, use an ampersand (&). This example passes the application path and the progress bar loading as parameters.
<div style="width:100%;height:400px;"> <script type="text/javascript" src="JSX/js/JSX30.js?jsxapppath=../workspace/JSXAPPS/MyProject&jsxapploader=0" </script> </div>
Any application configuration parameter is available using the jsx3.app. Server.getEnv() method. For more information, see General Interface API Reference.
This value can also be queried using the jsx3.app.Server.getEnv() method. For example,
myApp.getEnv("CONSTANT1");
225
jsx_logger_config. Specifies the name and location of the logging system configuration
file to be used. You can create a custom logging system configuration file and specify its location using this attribute. This is useful for monitoring and testing a deployed application at runtime. See Creating a Custom Logging System Configuration File. jsx_no_messages. When set to 1 , prevents JSX/locale/messages.xml from loading with the system. This file is used for system messages and is probably not necessary for a production deployment. jsx_no_locale. When set to 1, prevents JSX/locale/locale.xml from loading with the system. This properties bundle file provides all localized data to the system, including information for NumberFormat, DateFormat, Locale, and DatePicker. This data may not be necessary for some smaller applications. For more information, see Internationalizing and Localizing Applications. An application that specifies the jsx_no_locale parameter must not use any locale data. A common result will be a null pointer exception in DatePicker or TimePicker or null painted in Table, Menu, Select, Matrix, or BlockX.
jsx_browsers. Overrides the default set of supported browsers. The format of this parameter is bt={allow,warn}[,...] where bt is the browser type returned by the getType() method in the jsx3.lang.ClassLoader class. See jsx3.lang.ClassLoader in General Interface API
Reference. For example, to show a warning in Internet Explorer 6, modify the application launch page as follows: <script src="JSX/js/JSX30.js" jsx_browsers="ie6=warn"/>
allow launches the application in the browser. warn provides a warning for unsupported browsers and allows the user to
proceed. The following Internet Explorer-specific parameters: jsxxmlregkey The default ActiveX XML object key. Specifies the version of the XML Parser instance as referenced in the Microsoft Windows Registry. For example, jsxxmlregkey="Msxml2.FreeThreadedDOMDocument.4.0".
jsxxslregkey The default ActiveX XSL object key. Specifies the version of the XSL
HTTP control as referenced in the Microsoft Windows Registry. For example, httpregkey="Msxml2.XMLHTTP.4.0".
jsxxmlversion Specifies the version of the previous three keys---XML Parser, XSL
By default, General Interface 3.5.1 and 3.6.0 load version 6 if available, then version 4 if available, then version 3. If you need to use a different version, use these system parameters to override the defaults. General Interface runtime parameters are available using the jsx3.getEnv() method. For more information on the getEnv() method, see General Interface API Reference. As an example of configuring the runtime, you might configure the General Interface runtime to print a value to the system log. The following example assigns a value of value1 to a General
Copyright TIBCO Software Inc. All Rights Reserved.
226
to print a value to the system log. The following example assigns a value of value1 to a General Interface runtime parameter named jsxprop1 :
<script type"text/javascript" src="JSX/js/JSX30.js" jsxprop1="value1"> </script>
would print the following output to the system log: The value of jsxprop1 is value1.
Using Cross-Domain GI
The cross-domain loading feature allows you to load the General Interface runtime and your application from different security domains, increasing deployment flexibility and allowing you to do the following: Host the GI runtime on a content delivery network (CDN) for improved load times. Use a single runtime installation for several General Interface applications, including applications that are hosted on different domains. This can improve load time since the GI runtime may already be in the browser cache. Include General Interface applications in blogs and other management systems where hosting files is not permitted. Allow a system administrator to install a single instance of the General Interface runtime to be shared across an organization to simplify application deployment for users. In a build of GI that supports cross-domain loading all XML and XSL data file have been converted into a JSONP-like format, which supports loading across domains. For example, the file JSX/locale/messages.xml,
<data jsxnamespace="propsbundle" locales=""> <locale> <!-- jsx3.lang.ClassLoader --> <record jsxid="boot.env_reset" jsxtext="Error redefining JSX environment parameter {0} from ''{1}'' to ''{2}''."/> <record jsxid="boot.class_err" jsxtext="Could not load class {0}."/> <record jsxid="boot.class_ex" jsxtext="Error loading class {0}: {1}"/> <record jsxid="boot.class_undef" jsxtext="Loaded JavaScript file {0} but class {1} was not defined."/> ...
becomes JSX/locale/messages.xml.js,
227
jsx3.net.Request.xdr( "jsx:/locale/messages.xml", "<data jsxnamespace=\"propsbundle\" locales=\"\">\n\n <locale>\n <record jsxid=\" boot.env_reset\" jsxtext=\"Error redefining JSX environment parameter {0} from ''{1}'' to ''{2}''.\"/>\n <record jsxid=\"boot.class_err\" jsxtext=\"Could not load class {0}.\"/>\n <record jsxid=\"boot.class_ex\" jsxtext=\"Error loading class {0}: {1}\"/>\n <record jsxid=\"boot.class_undef\" jsxtext=\"Loaded JavaScript file {0} but class {1} was not defined.\"/>\n ... ");
This conversion is completely automated by the build process, which uses the new JsEncodeTask task to compile the XML/XSL resources. The task is turned off by default to avoid some code and data bloat. To enable it you must set the build.gi.xd build property to true, either in build/user.properties or on the command line:
$> ant -Dbuild.gi.xd=true
A pre-built cross-domain ready distribution of GI is available for download as well. If you want to host your application on a separate domain as well, you must process the XML and XSL resources in your application in a similar manner. You can do so using the same Ant task that General Interface uses. There is also a command line interface for the encoder that comes with the General Interface source distribution:
$> cd WORKSPACE/JSXAPPS/myApp $> find . -name "*.xml" -or -name "*.xsl" \| xargs \ sh GISRC/build/tools/bin/jsencode.sh -user ../
Deployment
When deploying an application cross-domain you must modify the GI launch page to indicate the domains from which resources should be loaded in the cross-domain manner. Consider the following example: The GI launch page is http://www.example.com/myApp.html The GI application is http://apps.example.com/JSXAPPS/myApp The GI runtime is http://cdn.host.com/gi/3.9.0 Then the launch page should include the following:
<script type="text/javascript" src="http://cdn.host.com/gi/3.9.0/JSX/js/JSX30.js" jsxapppath="http://apps.example.com/JSXAPPS/myApp/" jsxxd="http://cdn.host.com/ http://apps.example.com/">
The two URLs in the jsxxd attribute indicate the cross-domain sites. Any resource whose path begins with one of these prefixes will be assumed to exist in the JSONP-like syntax and will be loaded in the cross-domain manner.
228
Synchronous Loading
Since the introduction of the Asynchronous Modular Platform in Release 3.7, General Interface relies less and less on synchronous loading. Some public APIs still trigger synchronous loading, however. These APIs are still available to use in applications, but they will not work if you deploy the GI runtime or your application cross-domain as described above. This is because the JSONP technique for cross-domain data access works only asynchronously. The following are examples of synchronous APIs. You must not use any of these in a cross-domain deployment.
jsx3.require() jsx3.net.Request.send() (when open() is called with bAsync=false) jsx3.app.Model.load() jsx3.xml.Document.load() jsx3.app.Cache.getOrOpenDocument() jsx3.lang.ClassLoader.loadJSFileSync()
XML URL (of jsx3.xml.Cacheable) when XML Async is false Persistence = Referenced (not Referenced Async) In addition, dynamic class loading relies on synchronous loading. Dynamic class loading occurs when an application loads a component file and one or more of the classes used in the component file is not already loaded. There are several possible workarounds to dynamic class loading: Use a custom build of GI that pre-loads all GI classes that the application uses. Use the AMP architecture and plug-in pre-requisites to declare the class requirements of each plug-in. Use the new 3.9 method jsx3.requireAsync() before calling Model.loadXML().
229
230
The General Interface Load Performance Optimization script is not included in the Enterprise Edition. Deciding which classes to include in a custom General Interface build requires an iterative process. First, run the General Interface Load Performance Optimization script with one set of classes and test the performance of the application. Then run the optimization script again with another set of classes and compare the performance to the first run. If you want to eliminate dynamic class loading, you should include every class that your application uses. Depending on how your application is structured, classes might be loaded that are only required by rare usage patterns. Therefore, the best solution might be to include only the classes needed to load the application to its first interactive state.
Set Up Requirements
Before you can create a custom build, you need the following: General Interface installation The General Interface Load Performance Optimization script, GI_HOME/util/gi-merge.sh An environment capable of running a Bash script, such as a Linux command line, Mac OS X terminal, or Cygwin shell
Quick Steps
Complete these steps to create, test, and deploy a custom General Interface build with the General Interface Load Performance Optimization script: 1. Set up to create a custom build. See Setting up for Custom Builds. a. Create a new deployment directory. b. Copy these files from the General Interface installation directory into the new deployment directory:
JSX/ directory jsx3.gui.window.html jsx3.gui.window.xhtml logger.xml shell.html shell.xhtml
c. Copy the General Interface optimization script from GI_HOME/util/gi-merge.sh to the same file system drive. 2. Create a custom build. Creating Custom Builds. a. Modify the script to customize the set of pre-loaded classes. b. Run the script. 3. Deploy the new custom build and the General Interface application to a web server. See Deploying Custom Builds. a. Copy the new deployment directory and the General Interface application to a web server.
Copyright TIBCO Software Inc. All Rights Reserved.
3.
231
a. b. Modify the path of the src attribute on the launch page or in the launch link to point to the deployment directory. 4. Test the application performance, modify the optimization script as needed and rerun it, and redeploy to test again.
3. Copy the General Interface optimization script, GI_HOME/util/gi-merge.sh, to the same file system drive as the new General Interface deployment directories you just created. To create customized builds for multiple General Interface applications, you need to create a deployment directory for each application. For example, if you are creating custom builds for three applications, you would create three deployment directories, such as gideploy1, gideploy2, and gideploy3.
2.
232
fully-qualified class name with periods ( . ) replaced with underscores ( _ ). For example, the jsx3.gui.Matrix class would be jsx3_gui_Matrix in the gi-merge.sh file. When you run the optimization script, classes with the variable set to 1 are included in the custom build. The script automatically resolves dependencies between classes. For example, if you include the jsx3.gui.Button class, the jsx3.gui.Form class is also included because Button implements Form. Any classes that are set to 0 and that aren't required by an included class are excluded. The following example shows a code snippet from a sample optimization script file. Classes with a variable of 1, such as jsx.gui.Form, jsx.gui.Heavyweight, and so on, are copied to the custom build.
. . . jsx3_gui_Dialog=0 jsx3_gui_Form=0 jsx3_gui_Grid=0 jsx3_gui_HotKey=1 jsx3_gui_Image=1 jsx3_gui_ImageButton=1 jsx3_gui_LayoutGrid=1 jsx3_gui_List=0 jsx3_gui_Matrix=1 . . .
To run and test the optimization script, complete the following steps: 1. Open the command line according to your environment. 2. Change to the General Interface deployment directory. For example, if the custom build is located in gideploy1, change to that directory from the command line. The following example shows how to change to the gideploy1 directory in a Linux shell environment.
$ cd gideploy1
3. Enter the command to run the customized optimization script from the General Interface deployment directory. Because the optimization script modifies files in the JSX directory, always run the optimization script on each deployment directory, not on the General Interface installation directory. The following example shows how to run the command in a Linux shell environment.
233
$ sh /path_to_tool/gi-merge.sh
After running the optimization script, output similar to the following is printed to the command line and the listed classes are merged with the classes in the jsx.js files in the specified deployment directory. In this example output, jsx3_gui_Matrix is set to 1:
Creating backup of Creating backup Creating backup jsx3_gui_Matrix jsx3_gui_Matrix jsx3_gui_Matrix All done ie6/jsx.js of ie7/jsx.js of fx/jsx.js requires jsx3_xml_Cacheable requires jsx3_gui_Form requires jsx3_gui_Matrix_Column
4. Deploy the custom build and test the performance of your application with the new customized build. See Deploying Custom Builds. If you're not satisfied with the results, continue to modify the optimization script, rerun the optimization script, and test the application performance until you're satisfied with the results.
234
4. Use the application launch page to run the deployed application and test the performance. For example, to launch your application using shell.html as the launch page, enter a URL similar to the following in the browser: http://web_server/deploy_dir/shell.html?jsxapppath=../JSXAPPS/MyProjectDir where web_server is the address of the web server, such as localhost:8080 or mywebserver.com,
deploy_dir is the deployment directory on the web server, and MyProjectDir is the application
project directory.
235
About AMP
The Asynchronous Modular Platform (AMP) is a General Interface framework for building modular and high-performing enterprise-sized General Interface applications. AMP is an optional part of General Interface and is packaged as an add-in. AMP provides the libraries and templates that allow you to easily create extensible and loosely-coupled application components and combine them into a working whole. The design of AMP is inspired by the Eclipse plug-in architecture.
AMP Capabilities
This section describes common pitfalls of General Interface application development and how AMP helps overcome them to improve code quality and manageability.
Component Files
Component files that are unnecessarily large often contain many objects that are initially invisible and may only become visible during uncommon use cases. AMP helps manage component files so that they do not burden the overall code base. From the beginning of application development, AMP encourages decomposition of applications into constituent parts.
Code Components
Large, successful applications generally use a publish-subscribe pattern to notify application components of a change in application state. Unfortunately, this paradigm typically requires a great deal of boilerplate code, plus careful attention to components as they are added or removed from the application. AMP allows you to define these types of dependencies declaratively in XML, thereby significantly reducing the amount of required boilerplate code.
Copyright TIBCO Software Inc. All Rights Reserved.
236
Application Extensibility
It is common for large applications to lack extensibility features. Extending this type of application typically involves both coding the extension and modifying the application. If such an application is extensible, it is because the developer has spent considerable effort to design an extensible framework. AMP provides a modular framework that is engineered around the needs of extensible General Interface applications. The AMP infrastructure encourages and when appropriate, enforces, the design of application components according to well-defined interfaces that you can extend in the future without modifying the application.
Testing
In most application development environments, special care is required to build applications that can be easily tested. Because developers are usually pressed to complete development quickly, they may employ large, monolithic components, and create ad-hoc frameworks that are not designed with testing in mind. AMP addresses testing concerns by encouraging developers to create modular components and by offering an application framework with generous log coverage and benchmark statistics.
237
CustomPlugIn.prototype.onLoad = function() { var log = this.getLog(); this.getExtPoint("xp1").processExts(function(ext, xml) { log.info("Processed XML " + xml + " from extension " + ext + "."); }; };
The processExts() method implements a visitor pattern. The parameter to the method is a function that is called once for every child element of the XML declarations of every extension to the extension point. The following extension declaration
<extension-point id="xp1"> <!-- This extension point expects extensions to have one or more child elements of name "item." Each <item/> must declare a unique id attribute. --> </extension-point> <extension point="com.tibco.example.p1.xp1" id="x1"> <item id="1"/> <item id="2"/> </extension>
It is a good practice to document the contract of the extension point with its declaration using an XML comment, as shown above, or with arbitrary nested XML. Any nested XML is allowed, provided that it is not in the AMP XML namespace. AMP recognizes a processor child element of the extension-point element. This allows the extension point to define the processing visitor declaratively rather than in code. If the processor is declared in the extension point definition, the parameter to the processExts() method is optional. When no parameter is passed, a processor is created via the getProcessor() method of the jsx3.amp.ExtProc class. See the General Interface API Guide for more information.
Processor Types
This section describes the built-in processor types that cover the most common extension point contracts.
Type eval
The inner text content of every extension child element is taken as a script and evaluated in the context of the extension object. The extension elements may define the attribute load="true". In this case, the plug-in that defines the extension is loaded before the script is evaluated. Therefore, the script can be evaluated synchronously (load="false") or asynchronously ( load="true"). Example (Descriptor file):
238
<extension-point id="xp"> <processor type="eval"/> </extension-point> <extension point="com.tibco.example.p1.xp"> <eval load="true">this.getPlugIn().doSomething();</eval> </extension>
Type return
The inner text content of every extension child element is taken as a script and evaluated in the context of the extension object. The value of the evaluated script is returned by the extension processor. Example (Descriptor file):
<extension-point id="xp"> <processor type="return"/> </extension-point> <extension point="com.tibco.example.p1.xp"> <eval>this.getPlugIn()</eval> </extension>
In this case, the extension point contract does not specify whether or not the extending plug-in is loaded before the script is evaluated. Either the extending plug-in must be able to evaluate the code without being loaded or the processing plug-in must load the extending plug-in before evaluating the script.
Type return-async
This type is the same as the return type, except that the extension elements may declare load="true". In this case, the plug-in that declares the extension is loaded before the script is evaluated. The processor object returns an object of type jsx3.$AsyncRV instead of the actual value of the script, because the script may be evaluated asynchronously. Example (Descriptor file):
<extension-point id="xp"> <processor type="return-async"/> </extension-point> <extension point="com.tibco.example.p1.xp"> <eval load="true">this.getPlugIn()</eval> </extension>
239
Type instantiator
The instantiator type instantiates an object of a custom class for every child element of every extension declaration. The instance-class attribute should be the fully qualified name of a General Interface class. The class must define a constructor with the following signature:
function init(ext : jsx3.amp.Ext, xml : jsx3.amp.XML);
Registering this custom processor type allows the following processor definition in the plug-in descriptor file:
240
When a processor is defined declaratively for an extension point in the plug-in descriptor file, the argument to the processExts method is optional:
this.getExtPoint("xp").processExts().each(function(e) { jsx3.log("Extension: " + e); });
The processExts method returns the list of values returned by the process method of the processor, which was returned by the processor factory. The following extension definition
<extension point="com.tibco.example.p1.xp"> <item id="001"/> <item id="002"/> </extension>
would log the following when the extension processing code included above executes
Extension: p-001 Extension: p-002
The class attribute is the fully-qualified name of the class constructor function. The class must be defined before the plug-in is registered, because the plug-in cannot be instantiated if the class is not loaded. Therefore, define the class inline in the plugin.xml descriptor file (in a script element) or in an early load resource of a required plug-in. This also holds for custom extension point and extension classes. You can use custom extension point and extension classes by declaring the class attribute of their declarations.
<extension-point id="..." class="com.tibco.example.CustomExtPoint"/> <extension id="..." class="com.tibco.example.CustomExt"/>
Extending one of these classes allows you to define custom logic on instances of plug-ins, extension points, and extensions. You can use either of the following techniques; the appropriate technique depends on how you like to organize code and whether you want to define the same methods on a single instance or on multiple instances. Use the first technique when you want to define members on a single instance. Use the script, method, and field elements, and JavaScript resource with eval ="true" to define fields and methods on these objects. Extend a class if you want to define the same methods on multiple instances of a plug-in, extension point, or extension.
241
The array literal syntax ([function(){}][0]) is included to make sure that the script evaluates to the function reference rather than just declaring a function in the global scope. A non-AMP application defines an onLoad script that is executed as soon as the application paints for the first time. Instead of defining such a script in the Project Settings dialog, an AMP application extends the jsx3.amp.main.init extension point. The processor on this extension point is the simple eval type.
242
Plug-In: jsx3.amp.util.menumgr
This plug-in allows a menu bar to be composed of AMP extensions. This plug-in is helpful if an application requires an extensible menu bars or context menus.
Plug-In: jsx3.amp.util.prefspanel
This plug-in implements an extensible preferences panel. Panes may be added to the panel via AMP extensions.
Plug-In: jsx3.amp.util.wizard
This plug-in implements a wizard control. Wizard panes may be added to the wizard via AMP extensions.
Plug-In: jsx3.amp.util.toolbarmgr
This plug-in allows a toolbar to be composed of AMP extensions.
243
jsx3.app.UserSettings jsx3.gui.Alerts jsx3.gui.Block jsx3.gui.BlockX jsx3.gui.Button jsx3.gui.CheckBox jsx3.gui.ColorPicker jsx3.gui.DatePicker jsx3.gui.Dialog jsx3.gui.Form jsx3.gui.Image jsx3.gui.ImageButton jsx3.gui.LayoutGrid jsx3.gui.Matrix jsx3.gui.Matrix.Column jsx3.gui.Menu jsx3.gui.Painted jsx3.gui.RadioButton jsx3.gui.Select jsx3.gui.Slider jsx3.gui.Sound jsx3.gui.Splitter jsx3.gui.Stack jsx3.gui.StackGroup jsx3.gui.Tab jsx3.gui.TabbedPane jsx3.gui.Table jsx3.gui.TextBox jsx3.gui.TimePicker jsx3.gui.ToolbarButton jsx3.gui.Tree jsx3.gui.Window jsx3.gui.WindowBar jsx3.net.Form jsx3.net.Service jsx3.xml.Cacheable
Plug-Ins
Each AMP application comprises a set of AMP plug-ins, the functional units of an AMP application. As a developer, you decide how to decompose the application into its constituent plug-ins. Consider plug-ins to be application components that are either present (loaded) or absent (unloaded). In other words, design cohesive plug-ins that contain the parts of the application that function together, and tie plug-ins loosely to each other. When decomposing an application, keep in mind that an AMP application loads at the granularity of plug-ins; by default, all parts of a plug-in are loaded together. Plug-ins are defined with a plugin.xml descriptor file. Each plug-in has a unique identifier that is also the name of the directory in which the plugin.xml file is placed. In the following example, the plug-in identifier is com.tibco.example.p1.
Copyright TIBCO Software Inc. All Rights Reserved.
244
To register plug-ins, refer to them in the plugins.xml file, and place the file in the plugins directory at the root of the General Interface application that uses AMP. Alternatively, you can use the AMP API to register plug-ins programmatically. For each plug-in registered in the plugins.xml file, there should be a directory in the plugins directory with a name equal to the ID of the registered plug-in. Each of these directories should contain a plugin.xml file.
<plugins xmlns="http://www.tibco.com/gi/amp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tibco.com/gi/amp"> <plugin id="com.tibco.example.p1"/> ... </plugins>
You can locate the directory of a plug-in outside of the application's plugins directory. In this case, the path attribute of the plugin element should be the relative path from the plugins directory to the directory that contains the plugin directory.
<plugins> <plugin id="com.tibco.example2.plugin"/> path="../../otherApp/plugins/"> ... </plugins>
Copyright TIBCO Software Inc. All Rights Reserved.
245
An extension point is often designed to accept any number of extensions (one-to-many) but can also be designed to accept only one extension (one-to-one) or a specified number of extensions. The cardinality is not specified declaratively; it is enforced by the JavaScript code that processes the extensions. An extension point is declared in a plug-in descriptor file.
<plugin id="com.tibco.example.p1"/> <extension-point id="example-xp"/> </plugin>
An extension is a concrete implementation of the extension point contract. You can define an extension in the same plug-in that defines its extension point or in another plug-in. In both cases, the point attribute of the extension element is the fully-qualified identifier of the extension point. The fully-qualified identifier is the id attribute of the extension-point element appended to the identifier of its plug-in and separated with a period (".").
<plugin ...> <extension point="com.tibco.example.p1.example-xp"> ... </extension> </plugin>
The extension point-extension relationship is loosely coupled and controlled by the extension point. It is possible for an extension to extend an extension point that is not registered. Similarly, it is usually acceptable for an extension point to have no extensions.
246
<plugin ...> <resources> <script id="js" path="logic.js"/> <xml id="xml" path="data.xml" load="manual"/> ... </resources> </plugin>
Resources can declare a load setting with the load attribute, as in the example above. The possible values are early, normal (the default value), and manual. The load setting affects when the resource is loaded in relationship to the plug-in life cycle. AMP plug-in life cycle follows this process: 1. An AMP engine is instantiated for every AMP application. 2. The AMP engine processes plug-ins in the order that they are listed in the plugins.xml registry file. 3. For each plug-in, the following apply: a. Plug-in resources designated for early loading are loaded first. b. The plug-in is instantiated and registered. Its onRegister() method is called. At this point, some of the extensions to the plug-in's extension points may not be registered. c. As the rest of the plug-ins are registered, the plug-in's onExtension() method is called each time a plug-in is registered that extends one of its extension points. 4. After all plug-ins have been registered, the AMP engine is considered to be loaded and it publishes its LOAD event. 5. If and when the load() method is called on a plug-in, all of its normal loading resources are loaded, after which the plug-in is considered to be loaded, and its onLoad() method is called. 6. After the plug-in is loaded, any manual loading resources can be loaded programmatically. You can also define resources inline in the plugin.xml file. Instead of defining the path attribute, you can nest the file contents in a <data> element inside the resource element. For JavaScript and CSS resources, the nested <data> element is optional; for example, you can define a script in the text content of the <script> element.
The inline resource definition must be valid XML. Characters that are valid JavaScript or CSS but invalid XML must be properly encoded. Consider using a CDATA block for better readability.
<resources> <script id="js"><![CDATA[ this.getLog().info("Loaded resource js."); ]]></script> </resources>
XML, XSL and dynamic properties resources are defined inline as a document fragment. When defining these resources inline, make sure that you define the correct XML namespace for the content. If the xmlns attribute is not specified, the document fragment will inherit the AMP XML namespace.
Copyright TIBCO Software Inc. All Rights Reserved.
247
XML namespace.
<resources> <xml id="info"> <data> <info xmlns=""> <item id="1"/> </info> </data> </xml> </resources>
Similarly, a resource may require that another resource be loaded before it is loaded. A resource can also declare that a plug-in loads before the resource. This second option is useful for manual load resources for which the plug-in does not declare the dependency. In the following example, the com.tibco.example.lib plug-in loads before logic.js and logic.js loads before SampleClass.js.
<plugin id="com.tibco.example.p1"> <resources> <script id="js" path="logic.js"> <prereq plugin="com.tibco.example.lib"/> </script> <script id="SampleClass" path="SampleClass.js"> <prereq id="js"/> </script> </resources> ... </plugin>
248
The nested param elements are for documentation purposes only and are not validated at runtime. An event is published with the publish() method of the jsx3.util.EventDispatcher interface, which is implemented by jsx3.amp.PlugIn. It is up the developer to publish the event programmatically in JavaScript.
CustomPlugIn.prototype.save = function(strValue) { // Perform the save this.publish({subject:"saved", value:strValue}); };
Event registration can be performed declaratively as in the following example. The inner text of the subscribe element is taken as a script to be evaluated in the context of the plug-in that declares it. The variable evt is defined in this context and is equal to the event object that was published.
<plugin> <subscribe event="com.tibco.example.p1.saved"> this.getLog().info("The saved event was published with value: " + evt.value); </subscribe> </plugin>
Instead of declaring the event subscription as a block of JavaScript code in the content of the subscribe element, you can use the handler attribute to reference a method on the plug-in object that will handle the event.
<plugin> <method id="evtHandler" params="evt"> this.getLog().info("The saved event was published with value: " + evt.value); </method> <subscribe event="com.tibco.example.plugin.saved" handler="evtHandler"/> </plugin>
249
Asynchronous Execution
AMP is built from the ground up around asynchronous execution. All plug-ins and their resources are loaded asynchronously, and no synchronous APIs are provided. Asynchronous loading performs much better than synchronous loading, especially over a high-latency HTTP connection. Asynchronous loads do not block the browser's UI thread, whereas synchronous loads do block the UI thread. However, asynchronous JavaScript code is usually harder to develop than synchronous code. The result has often been an unfortunate trade-off between developer productivity and application performance. By contrast with other development environments, AMP effectively supports asynchronous programming through its declarative structure. Because AMP handles the asynchronous loading of all resources and their dependencies are defined declaratively, it is not necessary to write significant amounts of boilerplate code to load resources. AMP also takes advantage of the powerful asynchronous idioms in General Interface. The centerpiece of these idioms is the jsx3.Y() function, which declares an asynchronous method. Asynchronous methods defined using Y have a strict contract that helps promote uniformity across all asynchronous code. An example of these idioms is in the load() method of jsx3.amp.Resource. The following example shows how an action is performed when both rsrc1 and rsrc2 have loaded asynchronously.
this.getResource("rsrc1").load().and( this.getResource("rsrc2").load()).when(function() { // Perform an action });
See the General Interface API documentation for a detailed description of the jsx3.Y() method and its related objects.
Packaging Resources
Decomposition into components is a powerful tool for decreasing coupling between logical components and managing application complexity. AMP makes it easy to package resources into a cohesive plug-in. These resources can refer to other resources within the same plug-in without much boiler plate code and without reference to a global namespace. Plug-ins, extension points, and extensions can define fields and methods and execute arbitrary code inside the plugin.xml descriptor file. The elements script, method, and field can be children of the plugin, extension-point, or extension elements. In the following example, the script element this refers to the parent object.
250
<script> this.getLog().info("I am plug-in: " + this); </script> <method id="add" params="a, b"> return a + b; </method> <field id="strValue">"value"</field>
By convention, this is defined to be the parent object (plug-in, extension point, or extension) containing an XML text block that is interpreted as a script field. This convention is evident in the script element above, the declarative event subscription mechanism and the standard extension point processors, eval, return, and return-async. We recommend that you follow the AMP convention when you define how your own extension points interpret their extensions. Another useful feature is the eval attribute of a script resource. When this attribute is set to true , it causes the contents of the JavaScript file to be evaluated in the context of the plug-in instance. The following example shows how this is used in an external JavaScript file.
(function(plugIn) { plugIn.doSomething = function() { // do something here }; })(this);
251
<serialization xmlns="urn:tibco.com/v3.0"> <onAfterDeserialize><![CDATA[ objJSX._onBtnClick = function() { this.getPlugIn().performAction(); }; ]]></onAfterDeserialize> <object type="jsx3.gui.Button"> <strings jsxtext="Click Me"/> <events jsxexecute="this._onBtnClick()"/> </object> </serialization>
Build Tools
The source distribution of General Interface 3.8 includes build tools that specifically aid in the deployment of high performing AMP applications. One obvious downside of AMP applications is that application decomposition results in a large number of resource files. Loading a large number of files is usually much slower than loading fewer files, even when the sum size of the files is the same. This is especially true over an HTTP connection. The new tools are delivered as Ant tasks:
AmpResourceMergeTask. This tool merges the resources of a plug-in into the plugin.xml
descriptor file. This process takes advantage of the fact that most types of resources can be included inline in the descriptor file directly beneath the resource element. AmpPluginMergeTask. This tool merges plug-ins into the plugins.xml file. Just as resources can be included inline in plugin.xml, plug-ins may be included inline in the plugins.xml file. By using these tools, you can deliver an AMP application with as few as two files, by contrast with the large number of files that would otherwise be required. The files are:
config.xml, the General Interface application descriptor plugins/plugins.xml, the AMP plugins file
There are potential disadvantages in loading all resources in one file, because many resources may be used only in rare application use cases. For this reason, the build tools include options to merge a subset of the application plug-ins and resources.
252
<target name="mergeAmpPlugIns"> <!-- Define the AMP Ant tasks. jsx-tools.jar created from source distribution --> <taskdef resource="com/tibco/gi/ant/antlib.xml"> <classpath path="jsx-tools.jar"/> </taskdef> <!-- Merge specified resources into plugin.xml descriptor files. --> <amp-rmerge ids="com.tibco.example.p1.* com.tibco.example.p2.*"> <fileset dir="JSXAPPS/ampApp/plugins"> <include name="**/plugin.xml"/> </fileset> </amp-rmerge> <!-- Merge all descriptor files into plugins.xml --> <amp-pmerge pluginsfile="JSXAPPS/ampApp/plugins/plugins.xml"/> </target>
AMP Localization
This section describes how to localize an AMP application using localization features in AMP and in the General Interface Framework.
Resources
A plug-in can localize one of its resources by registering multiple versions of the resource, one for each locale. The locales attribute registers these versions and is supported for all resource types. It is a whitespace-separated list of locale keys, as in the following example.
<resources> <xml id="data" path="data.xml" locales="en fr de"/> </resources>
This resource declaration implies that the following files exist in the plug-in's directory.
data.xml data.en.xml data.fr.xml data.de.xml
The locale of the AMP application (jsx3.app.Server.getLocale()) determines which of the available files is loaded. In this example, the locales en_US and en would load data.en.xml. When no localized version of the resource is available for the locale, the default resource is loaded. In the example, the locale ja would load data.xml.
Plug-in Metadata
You can localize the plug-in descriptor file using a technique similar to that used for resources. With this technique, you can localize the metadata that is part of the extension point and extension declarations. Localized versions of plugin.xml are registered with the locales attribute of the plugin element in the main plugin.xml file. This attribute is a whitespace-separated list of locale keys for which the file is localized. For example, the following plugin declaration:
Copyright TIBCO Software Inc. All Rights Reserved.
253
implies that the following files are in the plug-ins directory in addition to plugin.xml, the contents of which are shown above:
plugin.es.xml plugin.de.xml
By contrast with localized resources, where the entire resource is replaced with the localized version of the resource, the contents of the localized version of the plug-in descriptor file are merged into the main descriptor file. This is handy because usually most of the plugin.xml content does not need to be localized (such as JavaScript functions). The following algorithm is used when merging the localized plug-in descriptor file into the main descriptor file: 1. Copy all attributes of the localized document element plug-in into the base file. 2. For each extension-point element in the localized document, search for an extension-point element in the base file with the same value for the id attribute. If that element exists, do the following: a. Copy all attributes from the localized element into the base element. b. If the localized element has one or more child elements, replace all the children of the base element with the children of the localized element. Elements script, method, field, and processor are not removed from the base element. 3. For each extension element in the localized document, search for an extension element in the base file with the same value for the id attribute. If that element exists, do the following: a. Copy all attributes from the localized element into the base element. b. If the localized element has one or more child elements, replace all the children of the base element with the children of the localized element. Elements script, method, and field are not removed from the base element.
There is no locale "fall through" for localized plug-in descriptor files. For example, if plugin.xml is localized for locales en and en_US, and the application locale is en_US, the merged file is the combination of just plugin.en_US.xml and plugin.xml. In this case, plugin.en.xml is not used in the merge. However, if plugin.xml is localized only for the locale en and the application locale is en_US, then the merged file is the combination of plugin.en.xml and plugin.xml.
Property Bundles
For fine grained localization using string replacement and message formats, AMP offers a properties bundle resource type.
<resources> <propsbundle id="messages" path="messages.xml"/> </resources>
The format of messages.xml is specified by the jsx3.app.PropsBundle class from the General Interface core library.
Copyright TIBCO Software Inc. All Rights Reserved.
254
Interface core library. After this resource is loaded, the localized strings that it contains are available in the following ways: Via the AMP API
plugIn.getResource("messages").getData().get("key")
One possible application of this functionality is in a extension point contract, as in the following extension point declaration:
<extension-point id="keys"> <!-- Expects any number of key elements. The id attribute is taken as a key from the messages resource of this plug-in --> </extension-point> <extension point="com.tibco.example.key"> <key id="key"/> </extension>
It is then up to the extension processing logic to interpret the id attribute as a property key:
var bundle = this.getResource("messages").getData(); this.getExtPoint("keys").processExt(function(ext, xml) { jsx3.log("Got key:" + xml.attr("id") + " and value:" + bundle.get(xml.attr("id"))); });
For more information, see the "Internationalizing and Localizing Applications" chapter in the General Interface Developer Guide.
255
PrefsController (via "File :: Settings...") jsx3.amp.main.progress extension point AMP metadata localization <binding> and support in MenuManager and ToolbarManager Event publishing/subscribing jsx3.amp.persist plug-in The running application has a series of menus and buttons that change the color of the background screen. In addition, there are two dialog examples to demonstrate a multi-screen "wizard" technique of gathering information and another to set a property.
There are a set of menus and buttons on the main layout screen that are populated during the initialization of each plug-in module. The selection of either the menu item or the button will change the application background to a different color.
Additionally, there is a plug-in with an associated menu called "Locale" that creates the text of each menu item by iterating through a list of language locales to convert them to their longer name. For example, the code "en" is transformed to "English".
256
In total, there are eight plug-in modules in seven directories that constitute the overall functionality of the application and each plug-in handles its own set of capabilities. The next section will begin investigating the structure of the AMPsample application. Structure A GI AMP project contains a directory named "plugins" and within it a descriptor file called "plugins.xml" is used to register each plug-in. An AMP engine is instantiated for every AMP application at runtime.
Each plug-in can be contained in its own directory structure. The name and path of the directory is part of the reference given in the plugins.xml file. The AMP engine processes plug-ins in the order that they are listed in the plugins.xml registry file. As part of the registry entry, a path can be provided to reference the containing directory. For instance, you can use a relative path to another project with the following:
<plugin id="green" path="../../otherApp/plugins/"/>
As the AMP engine processes each of the plug-in entries, it will assume the default path is relative to the "plugins" directory and will look for a directory with the same name as the plug-in "id" attribute. The plug-in directory will contain a file that describes the plug-in components and uses a default name of "plugin.xml". Note: it is also valid to bypass the referenced file and enter the same information entirely within the plugin element. However, keeping the plugin.xml file with the rest of its resources seems like a better practice. The format of the plugins.xml file adheres to the plugins.xsd schema located at http://gi.tibco.com/xsd/plugins.xsd and http://www.generalinterface.org/xsd/plugins.xsd. The AMPsample plugins.xml file contains the following XML: <plugins xmlns="http://www.tibco.com/gi/amp"
Copyright TIBCO Software Inc. All Rights Reserved.
257
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tibco.com/gi/amp http://gi.tibco.com/xsd/plugins.xsd"> <plugin id="init"> <method id="onRegister"> var uri = jsx3.app.Browser.getLocation(); var localeId = uri.getQueryParam("locale"); if (localeId) this.getEngine().getServer().setLocale(jsx3.util.Locale.valueOf(localeId)); </method> </plugin> <plugin id="main"/> <plugin id="red"/> <plugin id="yellow"/> <plugin id="purple"/> <plugin id="settings"/> <plugin id="locale"/> <plugin id="progress"/> </plugins> The first plug-in is identified by "init" and has a method available named "onRegister". The method's JavaScript will execute automatically after the plug-in is registered by the engine. Each plug-in is loaded in the order that it appears in the list; therefore the second plug-in is "main". Let's take a look at the plugin.xml file associated with main. <plugin xmlns="http://www.tibco.com/gi/amp" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.tibco.com/gi/amp http://gi.tibco.com/xsd/plugin.xsd" id="main" name="UI Plug-In" version="0.1"> The plugin.xml descriptor file starts out with the "plugin" element name and the schema names associated to namespaces. The attribute "id" matches the registered plug-in entry in the plugins.xml file and must be unique. The version attribute is arbitrary and could be used to
Copyright TIBCO Software Inc. All Rights Reserved.
258
plugins.xml file and must be unique. The version attribute is arbitrary and could be used to check if the version of the plug-in supports certain capabilities for example. The id, name and version attributes can be read programmatically using the jsx3.amp.PlugIn class API. The next section of the plugin.xml file describes which GI classes will be required in order for the plug-in to run properly. <requires> <plugin id="jsx3.gui.Block"/> <plugin id="jsx3.amp.util.menumgr"/> <plugin id="jsx3.amp.util.toolbarmgr"/> </requires> In this case, the "main" plug-in will depend on the three declared classes. The engine manages the loading of the classes. All required plug-ins will be registered and instantiated before the plug-in is registered. The next section of the plugin.xml file defines the resources used by the plug-in. Six resource types are allowed inside the resource tags: script JavaScript files; xml XML such as CDF and WSDL files; xsl XSL transformation files; css Cascading Style Sheet; jss GI dynamic properties file; propsbundle GI language properties. <resources> <script id="js" path="main.js" eval="true"/> <xml id="layout" path="layout.xml"/> </resources> An optional attribute can be added to a resource element to designate how the engine should load it. Three options are available: early, normal and manual. If the resource type is "script" and the "eval" attribute is "true", the engine will read the JavaScript and load it into memory. The life-cycle. <event id="colorChanged"> <param id="color" type="string"/> </event> Event processing.
Copyright TIBCO Software Inc. All Rights Reserved.
259
Event processing. <!- Extension Points -> <extension-point id="menu"> <processor type="instantiator" instance-class="jsx3.amp.util.Menu"/> </extension-point> <extension-point id="menu-item"> <processor type="instantiator" instance-class="jsx3.amp.util.MenuItem"/> </extension-point> <extension-point id="toolbar"> <processor type="instantiator" instance-class="jsx3.amp.util.ToolbarItem"/> </extension-point> <extension-point id="content"> </extension-point> Extension points <!- Extensions -> <extension point="jsx3.amp.main.layout" id="main-layout"> <eval load="true">var p = this.getPlugIn(); jsx3.$F(p.paint).bind(p)</eval> </extension> <extension point="main.menu" id="menus"> <menu id="file" label="File" path="/"> </menu> <!-<menu id="edit" label="Edit" path="/"> </menu> --> <menu id="view" label="View" path="/"> </menu> <menu id="help" label="Help" path="/"> </menu>
Copyright TIBCO Software Inc. All Rights Reserved.
260
261
About $Y
$Y allows you to write concise and readable asynchronous code, providing the following capabilities: A standard way to pass and handle callbacks and a standard way to send return values Multiple callbacks per asynchronous call Condition chaining Asynchronous method chaining via automatic parameter resolution Return value chaining You can use $Y instead of the following "anti-patterns" for asynchronous JavaScript programming: 1. Passing a callback function as a method parameter 2. Using publish-subscribe as an asynchronous callback
The following code examples all show an asynchronous method that loads an XML document and sample code that uses the method. The following code provides an example of anti-pattern 1:
function loadXmlAsync(url, callback) { var req = new XMLHttpRequest(); req.onreadystatechange = function() { if (callback) callback(req.responseXML); }; req.open("GET", url, true): req.send(); } loadXmlAsync("data.xml", function(doc) { jsx3.log("Got document: " + doc); });
As shown in the example, passing a callback function works but can get messy and there is no
Copyright TIBCO Software Inc. All Rights Reserved.
262
As shown in the example, passing a callback function works but can get messy and there is no standard idiom. The following questions may arise: Is the callback function the first method parameter or the last? Is the function required or optional? How are multiple callbacks executed? What is the signature of the callback function? How are return values handled? The following code provides an example of anti-pattern 2:
this.loadXmlAsync = function(url) { var req = new XMLHttpRequest(); req.onreadystatechange = function() { this.publish({subject:"done", doc: req.responseXML}); }; req.open("GET", url, true): req.send(); }; this.subscribe("done", function(evt) { jsx3.log("Got document: " + evt.doc); }); this.loadXmlAsync("data.xml");
The following issues may arise with anti-pattern 2: Mandatory event subscription is verbose. It is necessary to handle event un-subscription or risk garbage collection issues. An object with an asynchronous API can be used by only one object at a time. To support synchronous completion, the subscription must come before the asynchronous call. The object that publishes the event must implement the jsx3.util.EventDispatcher interface. The publish-subscribe pattern is designed for one-to-many, anonymous, and optional communication. This example is none of these. The following example shows how to use $Y to implement the function in the previous examples.
263
this.loadXmlAsync = jsx3.Y(function(cb) { var url = cb.args()[0]; var req = new XMLHttpRequest(); req.onreadystatechange = function() { cb.done(req.responseXML); }; req.open("GET", url, true): req.send(); }); this.loadXmlAsync("data.xml").when(function(doc) { jsx3.log("Got document: " + doc); });
A Simple Example
Any function passed to the when() method of jsx3.$AsyncRV is called when the asynchronous method is done. The function is passed a single parameter, which is the asynchronous return value of the asynchronous function, as in the following example:
var rv = loadXmlAsync("data.xml"); rv.when(function(doc) { jsx3.log("The asynchronous return value is: " + doc); });
Multiple Callbacks
A program can call when() any number of times before or after the asynchronous method finishes. Regardless of when it is called, all callbacks are invoked. For example:
var rv = loadXmlAsync("data.xml"); rv.when(function(doc) { jsx3.log("Got document: " + doc); }); rv.when(function(doc) { doSomethingElse(doc); });
Condition Chaining
Use the and() and or() methods of jsx3.$AsyncRV to chain asynchronous return conditions. Both methods also return instances of jsx3.$AsyncRV. For example:
Copyright TIBCO Software Inc. All Rights Reserved.
264
var rv1 = loadXmlAsync("data1.xml"); var rv2 = loadXmlAsync("data2.xml"); rv1.and(rv2).when(function() { jsx3.log("Got docs: " + rv1.rv() + " and " + rv2.rv()); });
The previous code is equivalent to but more concise than the following code.
var getURL = jsx3.Y(function(cb) { cb.done("data.xml"); }); var asyncURL = getURL(); asyncURL.when(function(url) { loadXmlAsync(url).when(function(doc) { jsx3.log("Got document: " + doc + " from URL " + url); }); });
265
window.setTimeout/jsx3.sleep
Other Y functions
Method Parameters
You can call the wrapping function with any parameters. Because the wrapped function takes exactly one parameter, cb, the parameters passed to the wrapping function are accessible via cb.args(). For example:
var asyncFct = jsx3.Y(function(cb) { jsx3.log("asyncFct called with args " + cb.args()); cb.done(); });
Return Value
You can define an asynchronous return value by passing it to cb.done(). The return value is passed to any callback registered with when(). It is also retrievable via the rv() method of jsx3.$AsyncRV. For example:
var asyncFct = jsx3.Y(function(cb) { cb.done("Hello World"); }); // Logs "Hello World" asyncFct().when(function(rv) { jsx3.log(rv); });
266
In an application in which many business logic functions depend on asynchronous primitives, $Y allows you to make these functions asynchronous without requiring extensive boilerplate code.
You cannot use variables of type jsx3.$AsyncRV with control statements, such as if. However, parameter resolution allows you to use parameters with control statements. As a workaround, you can pass such variables to another function.
Using $Z
$Z is another useful utility method that is similar to $Y. Like $Y, it returns a wrapping function that conforms to the contract of an asynchronous function. (The wrapping function always returns an instance of jsx3.$AsyncRV.) Unlike $Y, $Z enforces no contract on the wrapped function. jsx3.Z allows you to use automatic parameter resolution and return value chaining with normal, synchronous functions, as in the following example:
function add(a, b) { return a + b; } var firstArg = jsx3.Y(function(cb) { cb.done(cb.args()[0]); }); var one = firstArg(1), two = firstArg(2); jsx3.Z(add)(one, two).when(function(rv) { jsx3.log("1 + 2 = " + rv); });
267
In Resource: load(), loaded() For more information on AMP, see Asynchronous Modular Platform.
268
269
application, the Test Reorder helps you construct useful test cases with a minimum of extraneous noise.
3. Click the Launch Recorder button to open the Test Recorder recording interface. Before launching the Test Recorder, make sure that your browser opens pages in a new window instead of a new browser tab. This allows you to see what is occurring in General Interface Builder while you interact with the Test Recorder.
270
The recorder interface includes the following buttons and controls. Item Assert button Description Modal button that captures assertion conditions.
Wait button
Icons that toggle between Pause and Resume. Pause stops recording application interactions until the Resume button is clicked.
Recording an Application
As you interact with your application, the Test Recorder records the interactions and displays them in the test case table from which you started the Test Recorder. The process works as follows for the sample zip code application. This sample is available in the samples that ship with General Interface. To open the sample project, choose Project > User Projects > samples > WSDL_Mapping_1. 1. Enter a zip code, and a change event is recorded with the target object #zip. The change event is added as a row in the test case table tab from which you launched the Test Recorder. The event action is jsxchange, and the target is #zip. The Test Recorder also records event metadata, shown in the Value column, which allows the Test Recorder to play back the event.
271
2. Click Find City and State, and a new event is added to the test case table. The event action is jsxexecute, and the target is #lookupButton.
3. Another event is added when you dismiss the pop-up success message.
272
4. To verify that the application is working, click the Wait button. This puts the recorder in "wait" mode. The next click on the application will generate a wait test case instead of recording a model event. The recorder automatically picks what it determines to be the most appropriate command. You can change the command later, if needed, in the test case table. As shown in the next figure, clicking on a text box generates a jsxwait_value event.
273
In the sample zip code application, the target it #city and the value is "San Francisco." This means that when the action is replayed by GIPP or GITAK, it will wait until the value of #city equals "San Francisco." When constructing test cases, it is best to interact with the application and then do a single wait or assert operation. For a list of wait actions, see Working with the Test Case Table. When the recording is complete, you can go to the test case table and make modifications. In general, the recorder makes a best guess as to your intentions; however, because many interactions have multiple interpretations, you may need to manually edit some entries. For example, the next figure shows the result when the Wait button was clicked twice during recording. By returning to the test case table, you can delete the second instance of the wait event.
5. To keep the generated test cases, save the test case table. GIPP test cases require a .js extension and GITAK test cases require an .html extension. 6. After saving the recorded file, you can run the test case by launching it in GIPP or GITAK. Before doing so, make sure that GIPP and GITAK are configured. To do so, choose Tools > IDE Settings. Click GIPP & GITAK and specify the appropriate installation directory.
Copyright TIBCO Software Inc. All Rights Reserved.
6.
274
installation directory. 7. Click the Launch GIPP or Launch GITAK button in the builder window.
Clicking the Launch in GIPP button launches only the current file. To run GIPP with all of the available test cases, choose Project > Run Project in GIPP.
GIPP Actions
275
GITAK Actions
Target---Unique address for the GI object to which the action applies. The Test Recorder automatically resolves name collisions to assign a unique address. The syntax of this address is defined by the jsx.app.Model.selectDescendents() method. For more information, refer to the API documents available at http://www.generalinterface.org/docs/display/DOC/Learning+Center. Value---Argument or value of the action. Allowed values are determined by the action type. Examples may include a text value or 0 or 1 for a check box field. For model events, the value consists of metadata that was part of the event and object. The metadata is the schema of the model event object and includes the attributes that are necessary for the replay action. To record properly, it is necessary to know not only that there is a change, but what the change is. The schema in the value column can also include a previous value that is saved for possible future use.
276
To add an event, click Insert a Row. Choose the action from the drop-down list and specify the target. To edit an event, highlight the row and make changes as needed. To reorder rows, select them and drag from the leftmost column. To delete an event, highlight the event and click the Delete icon on the right. For , deleting the extra jsxexecute event and jsxwait_value events in the zip code example results in a simplified three-event test case, as shown in the next figure. The test case consists of the following events: Entering the zip code. Clicking the button. Waiting for the value "San Francisco" to be returned.
A GIPP test case is terminated by any row that: Contains a wait action. There can be only one wait action per test case. Defines a value for ID/Label. As you set or clear a value in the ID/Label column or toggle an entry in the Action column between a wait and other action, you can see the thick blank line that delineates the test case appear in the appropriate place.
277
The JavaScript code that defines the recorded events is located between the lines
/* BEGIN GIPP RECORDER */
and
/* END GIPP RECORDER */
The last line in the file invokes GIPP on the data structure, and must not be moved or removed. Below the link Insert manual tests here, you can optionally add documented GIPP methods. For example, the next figure shows the addition of a new test case, manual1, after the test1 test case.
The manual test case does not appear in the table in General Interface Builder, but it is included when the cases are actually run. For example, the next figure shows how the manual test case appears in GIPP.
278
When you click Launch in GITAK, GITAK opens with the test case displayed. The test suite is generated automatically to run from Builder. The purpose of the Test Recorder is to help you construct the test case. Note that the wait and assert actions are not listed.
279
Model Events
The custom control must use General Interface model events in the following ways: A model event must be published after any user interaction that changes the state of the control. This type of published event must define the event property _gipp and set it to be equal to 1. All events that the control publishes and which may have an arbitrary number of subscriptions must be published as a model event. A model event is published with the method jsx3.gui.Interactive.doEvent(). The following example shows a method that is called when the user clicks on a hypothetical control.
ClickCounter.prototype._ebClick = function(evt, elm) { if (this.value == null) this.value = 0; var newValue = this.value++; var veto = this.doEvent("click", {oldVal:this.value, newVal:newValue}); if (veto !== false) { this.value = newValue; this.doEvent("change", {newVal:newValue, _gipp:1}); } }
The first published model event, click, allows the event handler to veto the change in value that occurs by default when the user clicks on the control. It does not necessarily indicate a
Copyright TIBCO Software Inc. All Rights Reserved.
280
that occurs by default when the user clicks on the control. It does not necessarily indicate a change in value of the control, so it does not define the _gipp property. The second published model event, change, indicates that the control state did change, so it defines the _gipp property. This ensures that the event is recorded by the Test Recorder even if no event handlers are registered for the change event.
Playback
The custom control must include code that replays the recorded events and changes its own state as if the event were caused by a real user interaction. This code is invoked by GIPP or GITAK during test replay. To replay the recorded event, implement a replayEvent() method in the control's class, as in the following example.
ClickCounter.prototype.replayEvent = function(objEvent) { if (objEvent.subject == "change") { // handle the change event by changing the control value this.value = objEvent.newVal; this.doEvent(objEvent.subject, objEvent); } else { // handle click and other events that don't affect the control state this.doEvent(objEvent.subject, objEvent); } }
In this example, the replay logic sets the value of the control to the value of the newVal event property, which was set in the first code example when the change event was published. Typically, this method also calls doEvent() in case there are any subscriptions on the event. In this case, the newVal event property is necessary to replay the event properly. Without this property, the change in application state that occurs when the event is recorded can not be applied when the event is replayed. There must be similar cooperation between the code that publishes an event (with _gipp:1) and the code in replayEvent() that replays the event.
281
Menu Commands
This section describes General Interface Builder menu commands.
Project Menu
The Project menu includes the following commands. Command Description
New Project Displays a prompt to create a new project and opens the new project in the same browser window. A default project directory structure is also created on the file system. Recent Projects User Projects Project Settings Displays a list of the last ten projects that were opened. Clicking a project name opens the project. Displays a list of all projects in the workspace/JSXAPPS folder. Clicking a project name opens the project. Displays the Project Settings dialog for configuring project deployment, add-ins, class path, and legacy settings for the open project.
Deployment Displays the Deployment Utility which is used to generate code for deploying Utility the application in a browser. Create an HTML or XHTML launch page for standalone applications or generate HTML code to insert applications into an existing web page. Run Project Runs the current project configuration in a new browser window to simulate the runtime environment. The project runs in the same mode as General Interface Builder, such as HTML or XHTML. Runs the project in a new browser window on an HTTP web server as specified on the Paths panel of the IDE Settings dialog. If the HTTP server isn't configured, you are prompted to configure it.
282
File Menu
The File menu includes the following commands. Command Submenu Command New Description (Sheet 1 of 3) Creates a new, empty tab in the work area for the selected file type. GUI Creates an empty GUI component file. Save with the .xml extension Component in the components directory of the project. XML Document XSL Document JavaScript File CSS File Dynamic Properties File Properties Bundle Mapping Rule Open Recent Files Close Close All Revert Creates an empty XML file for content data, such as default values, for the application. Save with the .xml extension in the xml directory of the project. Creates an empty XSL file for transforming XML files containing application data. Save with the .xsl extension in the xsl directory of the project. Creates an empty JavaScript file. Save with a .js extension in the js directory of the project. Creates an empty CSS file for defining application styles. Save with a .css extension in the css directory of the project. Creates an empty dynamic properties resource file. Save with the .xml extension in the jss directory of the project. See Dynamic Properties Files. Creates a properties bundle file which contains a set of dynamic properties localized for one or more locales. See Internationalizing and Localizing Applications. Creates an empty mapping rules file for connecting to web services. Save with the .xml extension in the rules directory of the project. See Mapping GUI Components to Mapping Rules. Displays the File dialog for opening an existing file for use in the application. Displays a list of recently created files. Clicking a file name opens that file in the project. Closes the active tab. If the file contains unsaved changes, you are prompted to save the file. Closes tabs for all open files. If a file contains unsaved changes, you are prompted to save the file. Displays a Confirm Revert dialog where you can choose to revert the active file to the last saved state. After reloading, any recycled objects are cleared from the Recycle Bin and cannot be recovered. Displays a Confirm Revert dialog where you can choose to revert all open files to the last saved state. After reloading, any recycled objects are cleared from the Recycle Bin and cannot be recovered.
Copyright TIBCO Software Inc. All Rights Reserved.
Revert All
283
Saves the active file. For an XML cache document, saves the active file to the in-memory, local data cache. Saves the active file to disk and reloads the file appropriate to the file type. For example, JavaScript files (.js) are reloaded into the browser memory space to reflect the updated code. After reloading, any recycled objects are cleared from the Recycle Bin and cannot be recovered. This menu isn't available for open data cache files. Saves the active file with a different file name. For an XML cache document, opens the Save File dialog where you can enter a new file name and save the file to disk. Saves all open files in the project.
Tools Menu
The Tools menu includes the following tools. Command XML/XSL Merge Tool XML Mapping Utility Color Picker JavaScript Console Find and Replace General Interface Test Automation Kit IDE Settings Description Displays the XML/XSL Merge Tool, which displays the results of applying an XSLT document. You can open multiple instances of this tool. See XML/XSL Merge Tool. Displays the XML Mapping Utility, which is used to map WSDL, Schema, and XML documents to application objects. See Communicating with Data Services. Displays the Color Picker Tool for choosing color values. See Color Picker Tool. Displays the JavaScript Console for executing and debugging JavaScript code. See The JavaScript Console. Displays a search dialog for searching and replacing text in open text files. Links to the download site for General Interface Automation Kit, which you can use to test your General Interface applications. Displays a dialog for setting preferences for the visual authoring environment, such as IDE settings, IDE hot keys, and paths. See Customizing the IDE.
Palettes Menu
The Palettes menu includes the following palettes. Each of these palettes has a context menu. See Palette Context Menus. For more information on palettes, see Using Palettes.
Copyright TIBCO Software Inc. All Rights Reserved.
284
For more information on palettes, see Using Palettes. Command Description Keyboard Shortcut Ctrl+1 Ctrl+2 Ctrl+3 Ctrl+4 Ctrl+5 Ctrl+6 Ctrl+7 Ctrl+8 Ctrl+9
Component Displays or hides the Component Hierarchy palette. Hierarchy Properties Editor Events Editor Attributes Editor XSL Parameters Displays or hides the Properties Editor palette. Displays or hides the Events Editor palette. Displays or hides the Attributes Editor palette. Displays or hides the XSL Parameters palette.
Component Displays or hides the Component Libraries palette. Libraries Local Data Cache Project Files Displays or hides the Local Data Cache palette. Displays or hides the Project Files palette.
Recycle Bin Displays or hides the Recycle Bin palette. Objects that have been deleted using the Component Hierarchy palette can be recovered from the Recycle Bin. System Log Displays or hides the System Log palette.
Ctrl+l (lowercase L)
Help Menu
The Help menu includes the following commands. Command Online User Guides Description Opens the General Interface documentation page in a new browser window.
API Provides access to General Interface API Reference. You can view the API Documentation documentation in a dialog, a separate window, or the HTML version in a browser window. Also provides access to these additional references: General Interface GUI Property Reference General Interface GUI Event Reference General Interface XSL Parameter Reference Getting Started Provides a link to the Learning Center home page, which contains links to documentation, API reference, utility, samples, and other information.
Copyright TIBCO Software Inc. All Rights Reserved.
285
Search Discussion Forums Open Source Project Bug and Enhancement Tracking About General Interface License Agreement Welcome Screen Check for Updates
Provides a link to General Interface Open Source Project, which provides access to General Interface source code, public bug tracking, release builds, and developer forums. Opens the JIRA bug tracking window
Provides version information for General Interface and General Interface Builder, as well as important legal notices. Displays the License Agreement for the product. Launches the Welcome screen. See Welcome Screen. Checks for updates to General Interface.
Context Menus
To access a context menu, right-click an area of the user interface or right-click an object in a palette, such as a file name in the Project Files palette. Press the Escape or Left Arrow keys to close the menu.
286
Repaints the Live Component view in the work area to reflect changes. Refreshes the data in the cache and repaints the Live Component view in the work area. Available for objects that implement jsx3.xml.Cacheable. Sets the selected component(s) to transitory. When the component file is saved, the transitory object isn't saved to disk. Embeds the selected component(s). When the component file is saved, the embedded object is saved to disk. By default, components from the Component Libraries palette are embedded. Sets the selected component(s) to a reference. A referenced component is a link to a component file. For example, <include
src="workspace_/prototypes/greenbutton.xml" async="false"/>. The name of a referenced component in the
Referenced
Component Hierarchy palette is displayed using blue italic font. Referenced Sets the selected component(s) to an asynchronous reference. An Asynchronous asynchronous referenced component is a link to a component file that loads asynchronously. For example, <include
src="workspace_/prototypes/greenbutton.xml" async="true"/>. The name of a referenced component in the
Component Hierarchy palette is displayed using green italic font. Import Embedded Referenced Imports a copy of a component. When saved, the component is saved to disk. Imports a link to a component file, not the actual contents of the component. For example, <include
src="workspace/_prototypes/greenbutton.xml" async="false"/>. The name of a referenced component in the
Component Hierarchy palette is displayed using blue italic font. Referenced Imports a link to a component file asynchronously. For example, Asynchronous <include src="workspace_/prototypes/greenbutton.xml" async="true"/>. The name of a referenced component in the Component Hierarchy palette is displayed using green italic font. Export As XML As HTML Recycle Copy Name to Clipboard Exports the selected General Interface DOM branch as an XML file, which can then be used in other projects. Exports the selected DOM branch as an HTML file. This is useful for testing and printing. Moves the selected object(s) to the Recycle Bin. There is a separate Recycle Bin for each GUI component file. Copies the object(s) name to the clipboard.
287
Copies the Getter code for the object(s) to the clipboard. For example, myAddressLookup.getJSXByName("block").
288
Load/Reload Loads or reloads selected files from disk into browser memory. Copy Path Copies the file path to the clipboard. For example, js/logic.js.
If a file is read-only, a Lock icon displays on the work area tab. To open a locked, read-only file, double-click the Lock icon.
289
Wraps the text in the work area so all of the text is visible without horizontal scrolling. Displays the text without any wrap.
Delete Locale
Copies the project path to the clipboard. For example, workspace /JSXAPPS/myAddressLookup. Displays the Project Settings dialog where you can modify project settings, such as deployment, add-ins, class path, and legacy settings. See Project Settings Dialog. Runs the project in a new browser window.
290
Clone Reparse
Toolbar Commands
This section describes General Interface Builder toolbar commands.
291
Displays the active file in Formatted Source XML view. This view is read-only and is available for XML, XSL, dynamic properties, and GUI component files. Displays the active file in Rendered HTML view. This view is read-only and is available only for GUI components. Displays the active file in Component Profile view. This view is available only for GUI components.
Press the Enter key to navigate the Attributes Editor palette fields.
292
Moves the selected object and its children, if any, to the Recycle Bin. There is a separate Recycle Bin for each GUI component file. Shows or hides the focus rectangle in the work area. Most GUI objects can be selected in the work area using Ctrl+click. This button is off by default, because it can interfere with interactions and events of the selected object's children. Toggle snap-to-grid behavior for objects in the work area. Synchronizes the Component Hierarchy palette with the current version of the hierarchy on disk.
293
Controls docking options for the palette, which include the following: Fixed Positions the palette in the selected quadrant. Floating Floats the palette, which can be moved and minimized. Close Closes the palette. Creates a new tab in the work area for the selected file type. Displays the Open File dialog for adding an existing file to the project. Also opens the file in a tab in the work area. Opens the selected file in the project in a tab in the work area. Opens the File Profile dialog, where you can edit file ID, type, Auto Load, and URI values for the selected file. See File Profile Dialog. Removes the selected file from the project. The file isn't deleted from disk. Loads or reloads selected file(s) in the work area. Rescans project files from disk.
294
Press the Enter key to navigate the XSL Parameters palette fields.
295
DOM (Map Creates a new Form element (jsx3.gui.TextBox or and Create) jsx3.gui.Select) and adds it as a child of the active selection within the Component Hierarchy palette. Also creates the mapping. Detach Mappings Detaches values applied in the Settings panel. Removes all mapping rules for the selected rule(s).
Restrictions Removes all restrictions for the selected rule(s). Headers Delete Selected Rules Unselected Sibling Rules Generate Removes all HTTP headers for the selected rule(s). Deletes a selected rule(s) or all unselected rules. Deletes the selected rules from the tree. Deletes all siblings of the selected rule(s) from the tree.
Generates JavaScript code for the selected operation and places it on the clipboard for pasting into a JavaScript file. The rules file must be saved first.
Taskbar Toolbar
The taskbar is located at the bottom left of the General Interface Builder user interface. The taskbar toolbar has the following buttons:
296
Button
Description Opens the project directory in a new browser window. Right-click this hyperlink to access the taskbar context menu. See Taskbar Context Menu. Shows the work area and the palettes. Shows the work area only and hides all palettes.
Project The name of the project and project directory, which is created in the JSXAPPS Name directory. You can type the name or click the Browse button to browse to and enter a folder name in the JSXAPPS directory. Button Description Cancel Cancels the action and closes the dialog. Create Creates the project and launches General Interface Builder with the project open.
297
For more information on how JavaScript files are loaded, see Class Loading in General Interface. Manually/As Needed The JavaScript file is dynamically loaded when it's needed. For the file to be loaded automatically, it must be registered in a class path on the Classpath panel of the Project Settings dialog (Project > Project Settings) or loaded using a jsx3.require() method call. Otherwise, it can only be loaded programmatically with the Server.loadResource() method. If a JavaScript class file is registered on a class path, it doesn't need to be registered as a project resource to be dynamically loaded. At Init The JavaScript file is automatically loaded when the application initializes. When this option is selected, the file name in the Project Files palette is displayed in a bold black font.
Auto Load CSS Files Dynamic Properties Files Mapping Rules Files XML and XSL Files
Manually The file is loaded programmatically with the loadResource() or loadInclude() method. It's not recommended to load CSS files programmatically, because they can be very slow to load. XML and XSL files are typically set to Manually. They can also be loaded into cache using the XML URL property in the Properties Editor palette. Rules files are typically set to Manually. At Init The file is automatically loaded when the application initializes. When this option is selected, the file name in the Project Files palette is displayed in a bold black font.
GUI The Auto Load option is disabled for GUI component files. You can Component specify a GUI component file to automatically load when the Files application initializes in the Initial Component field on the Deployment panel of the Project Settings dialog. URI The path of the file relative to the project folder.
Buttons
The following buttons are on the bottom right of the File Profile dialog: Button Description Apply Save Applies the changes but doesn't close the dialog. Saves the changes and closes the dialog.
Cancel Cancels any changes and reverts back to the last saved version.
298
299
Add character encoding to XML declarations Give DOM focus to newly added GUI objects
Adds the encoding, specified in the Instead encode XML files as field, to the XML declaration. For example, if UTF-8 is specified, the XML declaration would look like this: <?xml version="1.0" encoding="UTF-8" ?>
Specifies whether to assign focus to a new object in the Component Hierarchy palette and the work area after it's created.
Warn before Specifies whether to display a warning dialog before a file is dereferenced in dereferencing the Project Files palette. a project resource file Warn before removing documents from the local XML cache Warn before deleting objects from the Component Hierarchy Open last project when launching General Interface Builder Show welcome splash screen on start Snap-to spacing Specifies whether to display a warning dialog before a document is dereferenced in the Local Data Cache palette.
Specifies whether to display a warning dialog before a component is recycled in the Component Hierarchy palette.
Specifies whether to open the last project when General Interface Builder is launched.
Specifies whether to display the Welcome screen when General Interface Builder is launched. See Welcome Screen.
Specifies the grid pixel size. Used when repositioning objects in the work area. To enable or disable the snap-to-grid feature, use the Toggle Snap-to Grid button in the Component Hierarchy palette.
300
Key
Paths Panel
The Paths panel allows you to set paths for the workspace and HTTP base. Field Description
Workspace A user home directory that contains your projects, custom add-ins and prototypes, and your user settings for General Interface Builder. Browse to an existing directory, create a new one, or accept the default workspace. HTTP Base The path in the HTTP Base field is used when you select Project > Run Project From HTTP. To use this feature, you must have an HTTP web server, such as Apache, hosting both the General Interface installation directory and your workspace directory. WS Path If the relative path between General Interface installation directory and your workspace directory aren't the same on the HTTP server as they are on disk, you must enter the relative path to the workspace directory in the WS Path field.
Buttons
The following buttons are on the bottom right of the IDE Settings dialog. Button Description Apply Save Applies the changes but doesn't close the dialog. Saves the changes and closes the dialog.
Cancel Cancels any changes and reverts back to the last saved version. Launches context-sensitive help.
File or Folder Name The name of the file to open or save or the name of the folder to choose.
Copyright TIBCO Software Inc. All Rights Reserved.
301
Buttons
The following buttons are on the top and bottom of the File Open, File Save, and Choose Folder dialogs. Button Description Moves up a directory level. Creates a new folder in the current directory. Reloads the dialog. Cancel Open Save Cancels any changes and closes the dialog. Opens the selected file (Open Files dialog). Use Shift+click and Ctrl+click to select multiple files. Saves the file and closes the dialog (Save File dialog).
Choose Chooses the selected folder and closes the dialog (Choose Folder dialog). Launches context-sensitive help.
Deployment Panel
The Deployment panel has settings for application deployment. For more information, see Deploying Applications. Field Caption Description The text to display in the browser title bar while the application is running.
Namespace Each General Interface application has a single jsx3.app.Server instance. The application namespace is a unique identifier for this single jsx3.app.Server instance. All objects in a General Interface application are governed by this server instance and uniquely located using the application namespace. The dot symbol (".") is supported in the namespace. For example, eg.chart.APP.
302
Initial The path to the component to automatically load when the application Component initializes at runtime. The path is relative to the project directory. For example, components/appCanvas.xml. Cancel Error Cancel Right-Click Mode Specifies whether to trap errors and display them in the System Log palette. If checked, JavaScript errors are routed to the System Log palette in General Interface Builder. If unchecked, JavaScript errors are routed to the browser. Specifies whether to trap the right-click event. If checked, developers can replace the browser right-click menu with a custom menu. If unchecked, right-click events are routed to the browser. The deployment mode for the deployed application used by the jsx3.net.Service class. Live Mode An online mode where the application is connected over HTTP/S to a back-end server, allowing access to online data. When requests for data are made by the application, the request goes out over HTTP/S and data is returned and rendered. Static Mode An offline mode where the application isn't connected to a server. Data is static and is referenced using static URLs stored in rules files. When a request for data is made by the application, the request is routed to a local static XML document. That static data is returned as if it came from a server and is rendered in the application. Select this mode when developing an application offline or disconnected from the server. This is useful when applications and back ends, such as web services, are in development simultaneously or a back end is currently unavailable. See Modifying Output Rules. Specifies whether to route key events that bubble up to the window from an application keyboard shortcut. If checked, the keyboard shortcut event bubbles up to the HTML body element and is then sent to the application. Check this option for deployment of standalone console applications. If unchecked, keyboard shortcuts only function if the focus is in the General Interface application. This option should be unchecked for deployment of non-console applications that are a portion of a web page. Determines how the application container behaves when movable objects, such as dialogs and CDF drag masks, are moved off the edge of the container. Scroll Movable objects cause the container to scroll. Expand Movable objects can leave the container. Hidden Movable objects are invisible. Specifies the locale of the localized application. Enter the two letter, ISO 639 language code and the optional, two letter ISO 3166 country code. The format is ll or ll_CC. For example, fr for French or fr_fr for French in France. See Locale Keys. If this field is empty, the locale is determined by the browser. For more information about localization, see Internationalizing and Localizing Applications. JavaScript code to execute when the application initializes. For example, you might want to execute a main method, communicate with a server, create controller objects by instantiating a controller class, or create the state of the application. For more information, see Executing Code When the Application Loads.
Overflow
Default Locale
onLoad Script
303
onUnload Script
JavaScript code to execute when the browser window is unloaded. There are several ways to unload a browser window, including closing the window, refreshing the window, or navigating to another URL. The onUnload event allows you to save user state and do any final cleanup before exiting. For more information, see Executing Code When the Application Unloads.
Add-Ins Panel
Select which add-ins to load for the project, such as Charting or custom add-ins. Restart General Interface Builder for changes to take effect. For more information on the Charting add-in, see General Interface Component Guide. Field Description
Charting If selected, General Interface Builder charting components display in the Component Libraries palette.
Classpath Panel
The project class path is used by General Interface to find custom classes that are dynamically loaded by your application. This accelerates load time for your application. For setting class paths, see Classpath Panel. For more information on how classes are loaded, see Class Loading in General Interface. For naming conventions for dynamically loaded classes, see Class Naming Conventions. Field Path Description The path to the custom classes. The class path is relative to the project directory. For example, entering js/ as the path would load the specified classes in the workspace /JSXAPPS/project_dir/js directory.
Event Specifies the event protocol for the project. The options include 3.1 (default) and 3.0 Protocol (deprecated). In General Interface 3.0, certain public methods, such as Tree.setValue(), generated model events, in this case the SELECT event. Such methods have been deprecated in General Interface 3.1 or have had their behavior changed so that model events aren't generated. In order to provide backward compatibility, a per-project setting was introduced in 3.1 that determines whether the project uses the 3.0 event protocol or the 3.1 event protocol. New projects use the 3.1 event protocol by default. Setting the event protocol to 3.0 maintains the behavior of General Interface 3.0.
Copyright TIBCO Software Inc. All Rights Reserved.
304
Buttons
The following buttons are on the bottom right of the Project Settings dialog: Button Description Apply Save Applies the changes but doesn't close the dialog. Saves the changes and closes the dialog.
Cancel Cancels any changes and reverts back to the last saved version. Launches context-sensitive help.
Welcome Screen
The Welcome screen provides links to projects, documentation, Developer Network, and General Interface Open Source Project. By default, the Welcome screen displays when General Interface Builder is launched. The Welcome screen can be enabled or disabled by toggling the Show at Startup option in the Welcome screen or the Show Welcome Splash Screen on Start option in IDE settings (Tools > IDE Settings > IDE Settings). The Welcome screen is also available from the Help menu. Item Create a New Project Description Launches the Create a New Project dialog. See Create a New Project Dialog.
Open an Provides a drop-down list of existing projects to open. Existing Project Recent Projects Provides a list of recent projects to open.
Documentation Provides links to User Guides and to API documentation in HTML format, if installed. Documentation downloads in HTML and PDF format are also available at http://www.generalinterface.org. Community News Community Provides information and links to General Interface announcements on Developer Network. Provides links to Developer Network, General Interface Open Source Project, and popular forum topics. Visit Developer Network at http://www.generalinterface.org for developer forums, information on getting started with General Interface, and other resources and information. Visit General Interface Open Source Project at http://www.generalinterface.org to browse source code, track bugs, and suggest enhancements. Show at Startup Specifies whether to display the Welcome screen when General Interface Builder is launched.
305
Color slider Use the slider to change color spectrum in the Color palette. Preview color box H (Hue) The box at the lower right displays the currently selected color. Click in this box to copy the hexadecimal (hex) color value to the clipboard. Specifies the color hue or gradation.
S Specifies the color saturation, which is the intensity or purity of a specific hue. (Saturation) B Specifies the color brightness or strength. (Brightness) R (Red) G (Green) B (Blue) Hex Specifies the red portion of the RGB value. After specifying a value, press the Enter key to view the updated hex equivalent. Specifies the green portion of the RGB value. After specifying a value, press the Enter key to view the updated hex equivalent. Specifies the blue portion of the RGB value. After specifying a value, press the Enter key to view the updated hex equivalent. The hex value for the selected color.
Deployment Utility
Use the Deployment Utility to create a launch page for your application, a launch link, or an inline div element. For more information, see Deploying Applications. To open the Deployment Utility, choose Project > Deployment Utility. The Deployment Utility has three panels: HTML Page Panel Launch Link Panel Inline Div Panel
306
Create
Regular If checked, JavaScript regexp syntax is supported in the Find field. For more Expression information, see Help > Internet Resources > Regular Expressions Guide (Mozilla). Replace Enter a replacement text string for the found text in the active open text file in the project.
307
Replaces the found text string with the replacement string. Replaces all occurrences of the text string with the replacement string. Finds the next occurrence of the text string. Closes the dialog.
XML/XHTML/Schema Select this radio button if you are using a XML, XHTML, or Schema as the source document(s) for generating the mapping rules. URL If WSDL is selected, choose the URL for the WSDL to be used for generating the mapping rules. If XML/XHTML/Schema is selected, enter the URLs for the outbound and inbound document(s). Documents that are created are "outbound," while documents that are processed are "inbound." Parses the selected document(s).
Parse Document
For more information, see Choosing the File for the Rules File Starting Point.
308
Displays name-value pairs for the selected rule. Many of the fields in the Rule Profile panel are editable. Typically, you would modify the node name and the target namespace. Description
Display When the Original Schema Source radio button is selected in the Rule Profile panel WSDL and the WSDL node is selected in the Rules Tree panel, this button is available in Source the Rule Profile panel. Depending on the size of the WSDL, displaying the WSDL might take some time.
309
URL to the input source file used to generate these rules. The input source file could be a WSDL, XML, XHTML, or Schema file. The name of the node as it appears in the XML message that is created or processed.
Operation The name of the operation as defined in the input source file. Name Rule ID Rule Type Simple Type Unique ID (jsxid) assigned by the General Interface system when the rule was created. The type of rule, such as WSDL, transaction, service, operation, input, output, element (E), attribute (A), complex type (C), and CDATA (D). Each rule type has an associated icon in the rules tree. For icon definitions, see Table 13. Set the value to 1 to denote that this rule is a simple type ( http://www.w3.org/2001/XMLSchema). Simple types include string, int, href and so on. For definitions of simple types, see the XML Schema at http://www.w3.org/2001/XMLSchema. XPath statement that points to the location of the node in the source document that was used to generate the rule. Maintains the binding between the source document and the rule node. If set to a specific URI, the node name is auto-prefixed (QName) to designate the target namespace. For example, <jsx1:zipcode>.
Settings Panel
The fields displayed in the Settings panel on the right side of the XML Mapping Utility depend on the type of rule selected in the Rules Tree panel. The type of rules include the following: Operation Rules Input Rules Output Rules Message Rules For information on how to use the Settings Panel, see Working in the Settings Panel and Communicating with a Web Service Tutorial.
Operation Rules
When an operation rule is selected in the Rules Tree panel, the following fields are displayed in the Settings panel. For more information, see Modifying Operation Rules. Field Endpoint URL Type Description This is the URL for the service to contact. It can be absolute (http/https) or relative (/services/address.asmx). To override this setting at runtime, call setEndpointURL on the Service instance.
310
Method
When making a Service call, the jsx3.net.Request class is used to transport the call. The most common methods are POST and GET. POST is used for sending XML content with the request. GET merely calls the given URL. To override this setting at runtime, call setMethod on the Service instance. POST GET PUT Submits data to be processed, such as a SOAP request envelope, to the identified resource. The data is included in the body of the request. Requests the specified resource, such as a URL. Uploads the specified resource.
DELETE Deletes the specified resource. HTTP Headers Each HTTP request can send different types of information. For example, the HTTP request can send any of the following: an XML document (POST), a URL overloaded with data of its own (GET or POST), or information about the content and purpose of the request itself. The HTTP headers listed in this field are automatically generated during the initial parse. If additional headers are needed, you can add them statically to this field. You can also add them at runtime on the Service instance by calling setRequestHeader for each additional header that should be added. Other headers not listed are also sent, including the content-length and any cookies used by the service.
Input Rules
When an input (request) rule is selected in the Rules Tree panel, the following fields are displayed in the Settings panel. For more information, see Modifying Input Rules. Field Stub URL Description Typically used in conjunction with the Stub Path field to support SOAP-based web services. When SOAP is used, each request document is encapsulated by a SOAP Envelope. The XML Mapping Utility treats the Envelope as a static document into which the actual request is placed. This document is generic enough to encapsulate the majority of SOAP messages. If this default document does not contain enough information, you can specify the URL for a static stub of your own. This value can be updated at runtime using the API calls, setOutboundStubURL or setOutboundStubDocument. Used in conjunction with the Stub URL field. Type a valid XSL query that describes where to place the generated document in the Stub document. This value can be updated at runtime using the API call, setOutboundStubPath.
Stub Path
onBeforeSend JavaScript statements entered in this field execute immediately before the request message is sent. This script executes in context of the Service instance. This means that the keyword, this, refers to the Service instance. For example, if you want to output the XML request to the System Log before sending it, you would enter:
jsx3.log(this.getOutboundDocument().getXML());
311
Output Rules
When an output (response) rule is selected in the Rules Tree panel, the following fields are displayed in the Settings panel. For more information, see Modifying Output Rules. Field Stub URL Description Enter the URL for a valid XML document (the typical response) when running the XML Mapping Utility in static mode (offline). The static mode allows you to test against a typical service response. This is useful in situations where the service isn't built yet or is inaccessible. To change the mode to static, choose Project > Project Settings > Deployment. This URL can also be set at runtime using the API call, setInboundURL. For more detailed information, see Modifying Output Rules.
onAfterReceive JavaScript statements entered in this field execute immediately after the response message is received and before the mappings are applied. This script executes in context of the Service instance. This means that the keyword, this, refers to the Service instance. For example, if you want to output the XML response to the System Log each time the service responds, you could write: jsx3.log(this.getInboundDocument().getXML()); For other examples, see onAfterReceive.
Message Rules
When message rules are selected in the Rules Tree panel, the following fields are displayed in the Settings panel. Message rules, which are children of input and output rules, include complex type, element, attribute, and CDATA rules. For more information, see Modifying Message Rules. Field Mappings Type Description The Mappings table is where the actual work is done. When a request message is generated or a response message is processed, each mapping listed in this table is run sequentially for the given rule. Although different mapping types exist, all mapping types provide a map between objects in the application (textbox, JavaScript variable, CDF attribute, and so on) and rules in the rules tree. For more information on mapping, see Communicating with Data Services. Script Filter or JavaScript code that evaluates in context of the Service instance. For example, you can set a value: setValue("0"); Maps to a node in the Local Data Cache palette. Type the cache document name, two colons, and a valid XSL Query. For example, myDocument:://recordjsxid=12. Maps to a GUI object in the General Interface DOM. Enter the object name.
NODE
DOM
312
Queries for or creates a CDF document in the Local Data Cache palette. Enter the CDF document name. Queries for or creates a CDF Record as a child of the current CDF record context. The Path/Value field is not required but can be used to support recursion or hand off processing to another rule. For example, if there is another rule in your mapping rules file that has a CDF Record mapping, you can enter the jsxid for that rule. To find the jsxid, select the rule that you wish to call and click the Rule Node Profile radio button. Queries for or creates a CDF attribute on the nearest CDF record ancestor. Enter the attribute name, such as jsxid, jsxtext, price, and so on. When Schema or WSDL are used as the input for the XML Mapping Utility, any restrictions appear in the Restrictions table. You can also add additional restrictions on a rule. For example, you might restrict user input to be equal to dog or cat. To restrict such input, you would add two new enumeration restrictions to the rule: one for cat, the other for dog. At runtime, these restrictions can be used to validate the request document as it's created node-by-node. For more information about what's published when a node value doesn't adhere to its restrictions, refer to the ON_INVALID subscription for the Service class. For more information, see Restrictions.
length maxLength
Specify an exact number of characters allowed in a string. For example, type 5 for a string to contain exactly five characters. Specify a maximum number of characters allowed in a string. For example, type 5 for a string to contain a maximum of five characters. Specify a minimum number of characters allowed in a string. For example, type 5 for a string to contain a minimum of five characters. Specify a regular expression to validate against. For example, entering the following regular expression would ensure that only numeric content can be entered by the user: /^d+$/ For more information on regular expressions, see Help > Internet Resources > Regular Expressions Guide (Mozilla). Specify an enumerated value to validate against. For example, you could limit the values for a stock to three values: symbol, CIK (Central Index Key), and CUSIP (Committee on Uniform Securities Identification Procedures). Specify a maximum inclusive value. The node value must be less than or equal to the specified value. Specify a minimum inclusive value. For example, the node value must be greater than or equal to the specified value.
minLength
pattern
enumeration
maxInclusive minInclusive
313
maxExclusive Specify a maximum exclusive value. For example, the node value must be less than the specified value. minExclusive Specify a minimum exclusive value. For example, the node value must be greater than the specified value. maxOccur Specify an inclusive maximum number of times this node can appear in the XML message. For example, type 5 for the node to appear a maximum of five times in the XML message. Specify an inclusive minimum number of times this node can appear in the XML message. For example, type 5 for the node to appear a minimum of five times in the XML message. Set to true to allow this node to be empty without being automatically removed by the XML Mapping Utility. The XML Mapping Utility automatically removes any node from an outgoing message that doesn't have text content or descendant nodes with text content. However, if an empty node has a nillable restriction that's set to true, the XML Mapping Utility leaves the empty node untouched. If you have a rule that might be empty when the outgoing message is being created and you want to make sure that it isn't removed, add a nillable restriction to the given rule.
minOccur
nillable
Field
Description
Repeat As long as the JavaScript code in this field evaluates to true, the rule and all When descendant rules are run again. The JavaScript function is used to create and define a collection from a single node. The collection is added as nodes in the XML message to the server. Don't enter true in this field, because it results in an infinite loop. The Repeat When field is only applicable to outbound (input) messages. It's typically used by mapping rules that convert a JavaScript array into an XML Node-set in the outgoing message. Conceptually, this feature is similar to a do-while loop, where execution will happen at least once and continue as long as the while (Repeat When) statement is true. For examples, see Repeat When. Also note that CDF mappings automatically repeat when necessary. For more information on CDF GUI components, see Mapping Response Data to CDF GUI Components.
Mapper Log
The Mapper Log displays information about the outcome of parsing the starting point document and testing mappings. For more information, see Mapper Log and Mapper Log Toolbar. Field Description Text area Displays the XML Mapping Utility log messages according to the selected log level. Use the Adjust Log Level button to select a log level.
314
Create Panel
Mappings for the outbound message display on this panel. Field Outbound Mappings Rule Name Type Field Description Mappings of GUI objects to mapping rules for the outbound message. Name of the element (mapping rule). Type of object that is mapped. Types include Script, NODE, DOM, CDF Document, CDF Record, and CDF Attribute.
Path/Value GUI component name or any associated JavaScript code for this mapping. Post-Mapping Filter/Handler Filter code to execute before sending this message.
Send Panel
The outbound message displays on this panel. Field URL Description URL specified in the WSDL file.
Copyright TIBCO Software Inc. All Rights Reserved.
315
Header content for the message. The header text can be edited. User name used for authentication if required.
Password Password used for authentication if required. Method Method for contacting the Service. Choose from POST, GET, PUT, and DELETE. The most common are GET and POST.
Receive Panel
The Service response displays on this panel. Field Description
HTTP Headers Header content for the response message. HTTP Status Response Status of message, such as 200, 404, and so on. Response message.
Apply Panel
The inbound mappings display on this panel. Field Pre-Mapping Filter/Handler Inbound Mappings Rule Name Type Field Description Filter code to execute on the inbound document. Mappings of response rules to application objects. Name of the element (mapping rule). Type of object that is mapped. Types include Script, NODE, DOM, CDF Document, CDF Record, and CDF Attribute.
Path/Value GUI component name or any associated JavaScript code for this mapping.
316
Script Source
JavaScript code that produces an XML document or a node in an XML document as output. XML or XSL code typed directly into the tool dialog. If URL, Cache, or Script is used to specify the XML or XSL source, this field displays the file contents. In the case of XSL, modifications can be made before the merge operation.
Merge Merges the XML document with the XSLT filter document and displays the Documents results. Rendered Output Raw Output Displays the result of the merge operation as rendered XML or HTML (as it would appear in a browser). Displays the result of the merge operation as XML or HTML.