Idiom World Server SDK Tutorial
Introduction
The main reason that I am writing this document is to gain more knowledge on Idiom SDK and at the same time to prepare some reference materials for my Idiom development work. From my past experience, I found the best way to learn a new technology is to prepare training materials for future use. In this tutorial, I am going to focus mainly on Idiom SDK and I will be using Idiom SDK User Guide and the samples bundled in Idiom server.For any additional information on Idiom, please visit http://www.idiominc.com.
Installation and Development Tool Setup
I will assume you already have Idiom installed and a development tool like Eclipse, Netbeans or Notepad.
Please also see How to Set Up Remote-Debugging in Idiom with Eclipse.
World Server SDK
1. General Info
The lack of official SDK support before the release of 6.5 resulted in two major problems:
1. Extensive support by Idiom due to the complexity of the WorldServer API and insufficient documentation.
2. Backward compatibility issue due to the exposure of the core WorldServer API for custom development.
After the 6.5 release, Idiom customers can benefit from:
1. Customer controlled WS customization
2. Ability to integrate with external applications via Web services
3. Guaranteed Backward Compatibility
WS SDK Types:
1. Server SDK (wssdk-server.jar)
- WS components (filters, automatic actions)
- command line tools
2. SDK Components
3. Client SDK (wssdk-client.jar)
- Web services for Java and .NET
To run the build script for samples, you need to have Ant and J2SE SDK 1.4.2 or higher.
2. SDK API Components
There are three structures in WS SDK – objects, object mangers and object interfaces. Through these structures, WS services can be accessed.
i.g. Object Interface <-> Object Manager <-> WS Services
2.1 Object Managers
The object managers provide lookup, creation and deletion services for SDK objects. To obtain an instance of an SDK object, you need to obtain a handle to the object manager. After the handle is obtained, using it to retrieve an SDK object. One distinction between SDK object and object manager is that object managers must be only accessed within a specific WS context. This means you must obtain a handle to a WSContext object and use it to request an object manager. Once it is done, the obtained object manager can be accessed via the corresponding object interface. If the WSContext object is not available, the linked SDK object and object manager instances will also become inactive.
2.2 Custom Access Modules
- External Service Module: a standalone application or a process run as a part of another application
e.g. TM lookup services
- Component Module: a program written using the SDK that is designed to be uploaded into WS.
It can only run as a part of WS, not from outside of WS.
e.g. Automatic Actions, Servlets, etc
2.3 Service Framework
The service framework provides the instance of the WSContext at execution time and initializes all environments.
- Standalone Execution Model and Pluggable Component Model
- WS will control the execution of component modules, but WSContextManager class has to be used to run external modules.
- Transaction Control
One example for a generic external service module from SDK User Guide:
1. WSContextManager.runAsUser(Username, Password, WSRunnable) method is invoked with a custom class that extends the service framework WSRunnable interface. (User login information is required as well.)
2. The WSContextManager delegates to the internal TranslationRunner, which:
a) Initializes the system; this step is not illustrated
b) Creates a new transaction
c) Logs in the user
d) Executes the WSRunnable.run(WSContext) providing the WSContext that is now associated with the created transactions
3. A new transaction for the WSContext is created.
4. The user credentials are validated.
5. Process enters custom WSRunnable.run method.
6. Uses the WSContext object to get an instance of an object manager object.
7. Uses the object manager to gain access to a particular SDK object for accessing services.
8. Uses the SDK object to access WorldServer service or to manipulate data.
9. Returns true to commit changes, or false to rollback. TransactionRunner receives the return value and either commits or rollbacks changes
10. Process completes
3. Creating Modules
3.1 External Modules
External modules need to use the static WSContextManager class and the WSRunnable Interface.
1. Implement WSRunnable interface
2. Implement business logic in the required run method
3. Use WSContextManager to execute WSRunnable
- Creating Command-line Tools: the steps above or by extending WSCommand class.
3.2 Custom Component Modules
- Supported components: AIS Triggers, Automatic Actions, Authentication, Filters, Notification Service, Servlets, TM Services.
As to the Servlets, WSHttpServlet class is required and handle method in it has to be implemented.
3.3 Deploying Components
- Using WS UI
- WSComponentManager can be also used as a command-line utility.
java com.idiominc.wssdk.component.WSComponentManager <username> <password> <component archive path>
3.4 Creating Triggers
1. Extend the WSAisTrigger class.
2. Implement public void execute(WSContext context, Map parameters, int eventType, WSNode node)
3. Override public WSParameter[] getParameters()
3.5 AIS Connectors
- Extend WSConnector.
- The methods in WSConnector in turn require you to implement several other classes.
3.6 Attribute Validators
1. Extend WSAttributeValidator.
2. Implement WSAttributeValidator.getAttributeTypes() and WSAttributeValidator.validate(WSContext, WSAttributeDescriptor, String)
3.7 Automatic Actions
1. Extend WSTaskAutomaticAction or WSProjectAutomaticAction.
* Two abstract methods should be implemented: getReturns and execute.
2. Implement execute method.
3. Override public WSParameter[] getParameters() or use WSParameterFactory class.
e.g. Pass Filename to Commnad? Yes or No
public WSParameter[] getParameters() {
String [] SELECTOR_OPTIONS =
new String [] { “Yes”, “No” };
WSParameter USE_SELECTOR =
WSParameterFactory.createSelectorParameter
( USE_SELECTOR_PARAM_NAME,
“Pass Filename to Command?”,
SELECTOR_OPTIONS);
WSParameter [] AUTOACTION_PARAMETERS =
new WSParameter []
{ USE_SELECTOR };
return ( AUTOACTION_PARAMETERS );
}
4. Implement public String[] getReturns() to show what the appropriate transitions are for this autoaction.
e.g.
public String[] getReturns() {
String [] AUTOACTION_RETURN_VALUES =
new String []
{ SUCCESS_RETURN_VALUE ,
FAILURE_RETURN_VALUE };
return ( AUTOACTION_RETURN_VALUES );
}
5. Add Exception handling
Two different exceptions:
- “Try again” exceptions: database deadlock, a data repository deadlock, concurrent object modification, etc
- The rest: fatal errors that will be re-routed to the human error step.
*** Don’t catch everything using catch (Exception e) {…}. Catch the specific error conditions and leave the rest of the error handling for the framework.
3.8 Password Policy Authentication Component
1. Extend WSPasswordPolicy.
2. Implement public String validatePassword(WSContext wsContext, WSUser user, String suggestedPassword)
3.9 Filter Component
WorldServer invokes filters any time content is opened or identified to be segmented. The segments produced by the filters are stored within the WorldServer metadata and are used to provide translatable pieces of the asset.
1. Extend WSFilter abstract class.
2. Must be implemented:
public abstract void parse(WSContext wsContext, WSNode sourceNode,WSSegmentWriter writer)
WSContext: access to the WS services
WSNode: access to the asset content
WSSegmentWriter: provides the facilities through which new segments are to be generated from the asset content
Optional:
public boolean showMarkup()
public void save(WSContext context, WSNode targetNode, WSSegmentReader reader)
* Make sure to call the base class save.
public int countWords(WSContext context, String text)
public boolean isCachingAllowed()
3.10 Notification Services Component
1. Extend WSNotificationServiceComponent abstract class.
2. None of the methods need to be overloaded unless you want to modify the message for the associated event. Modify WSEmailMessage for customized messages.
public void makeTaskAssignMessage(WSContext context, WSTask[] tasks, WSEmailMessage defaultMsg)
public void makeTaskDueMessage(WSContext context, WSTask[] tasks, WSEmailMessage defaultMsg)
public void makeTaskOverdueMessage(WSContext context, WSTask[] tasks, WSEmailMessage defaultMsg)
public void makeTaskStepDueMessage(WSContext context, WSTaskStep[] taskSteps, WSEmailMessage defaultMsg)
public void makeTaskStepOverdueMessage(WSContext context, WSTaskStep[] taskSteps, WSEmailMessage defaultMsg)
3.11 Servlet Component
1. Extend WSHttpServlet class.
2. Implement handle method. WS Servlet is identical to standard Java servlets.
public abstract boolean handle(WSContext context, HttpServletRequest request, HttpServletResponse response)
public String getDefaultOutputEncoding()
Accessing the servlet:http://localhost:8080/ws/ws_ext?servlet=[name]&token=[token]
* token=-1 can be used for Context URL to generate a valid session token, but can not be used at the browser address bar directly.
3.12 Translation Memory Repairs
Repair components allow you to define how to correct differences between the the lookup text and the source text, and how to correct the target.
1. Extend WSTranslationRepairComponent class (Currently implemented as Singleton).
2. Implement WSRepairResult performRepair(WSWordsUtility lookupText, WSWordsUtility matchSourceText, WSWordsUtility matchTargetText)
- WSWordsUtility: Mutable.
Changes should be made to matchSourceText and matchTargetText objects, not to the lookupText object.
- WSRepairResult: Result of the repair processes back to WS.
Key Utility Methods:
WSWordBreaker getWordBreaker(Locale)
Boolean isRepairEnabled(String repairName, Locale sourceLocale, Locale targetLocale)
3.13 Translation Memory Services Component
- TM AIS Path Normalization
If the AIS paths of two files are the same, the TM will store only a single set of translations. This process happens before each asset is leveraged.
- Segment Auto Translation: this process will determine when the source should be used to directly translate the target segment.
* One caveat is that the TM is calling this method (normalizePaths()) everytime it is being accessed.
Even when you import a TMX TM export, the method will be called, so it should be well optimized.
- Must extend the core WSTmServicesComponent class.
- Override public String[] normalizePaths(String rawSourcePath, String rawTargetPath) , or public String autoTranslateSegment(String sourceText, Locale sourceLocale, Locale targetLocale)
3.14 UI Hooks
1. Extend the WSUIHooksComponent class (Singleton)
2. Override public String generateXXXSnippet(WSContext context, HttpServletRequest request) where XXX represents the identifier for the page to be customized.
3.15 Word Breakers
Changing default word breaking behaviors will affect TM and TD, so it needs to be fully tested after any changes have made to it.
1. Extend the WSWordBreakerComponent class.
2. Override WSWordBreaker.Word[] breakSentence(String sentence)
The text provided will not contain any placeholders, so it is safe to assume that the text only contains words, numbers, whitespace and punctuation.
WSWordBreaker.NumberElement createNumberElement(String content, String prefix, String suffix)
WSWordBreaker.TextElement createTextElement(String content, String prefix, String suffix)
WSLanguageId getSupportedLanguage()
* If you want to replace the default word breaker, you can specify WSLanguageId.DEFAULT.
3.16 Word Stemmers
E.g. “cats” (and possibly “catlike”, “catty” etc.) as based on the root “cat”
1. Must extend the WSStemmerComponent class.
2. Overridevoid generateStem(WSStemmable word): WSStemmable is mutable.
WSLanguageId getSupportedLanguage() String getName()
3.17 WSContext
Examples:
WSAisManager manager = context.getAisManager();
if ( manager == null ) {
return new WSActionResult(WSActionResult.ERROR,
“Unable to obtain AIS Manager.”);
}
try {
log.debug( “Copying ” + assetTask.getSourcePath() + ” to ” +
assetTask.getTargetPath() + “.” );
manager.copy( sourceNode, assetTask.getTargetPath() );
} catch (WSAisException e) {
log.debug( e );
return new WSActionResult(WSActionResult.ERROR,
“Error copying asset: ” +
e.getMessage() );
}
3.18 WSTask
Examples:
//getting a system file path of a source asset:
String SourceSystemFilePath= assetTask.getSourceAisNode().getFile().getPath();
//Getting a target locale name of a target asset:
String TargetLocaleName = assetTask.getProject().getTargetLocale().getName();
4. Additional WorldServer Configurable Objects
4.1 Human Action Definitions
In desc.xml, add <human_action name=”action name” instructions=”user instructions” />
4.2 AIS Property Definitions
In desc.xml, add:<ais_property name=”property name” inheritance=”inheritance type” type=”property type”> <option value=”option1”/> <option value=”option2”/> </ais_property>
4.3 Attribute Definitions
In desc.xml, add:<attribute name=”attribute name” ui_name=”ui name” object_type=”object_type” flags=”flags” type=”attribute type”> <option value=”option1”/> <option value=”option2”/> </attribute>
4.4 Mime Type Definitions
<mime_type type=”MIME type” description=”type description” is_text=”is textual type?” default_extension=”default file extension” external_type=”external type” filter=”filter name” extensions=”list of file extensions”>
5. Class Mappings from Core to SDK
No Comments
Leave a comment