Sunday, June 20, 2010

Creating a Smart Tag

So far I have only been able to get the recognize portion of the smart tag to work. The code for the working portion is here:
package com.example;

import com.sun.star.container.XStringKeyMap;
import com.sun.star.i18n.Boundary;
import com.sun.star.i18n.WordType;
import com.sun.star.uno.XComponentContext;
import com.sun.star.lib.uno.helper.Factory;
import com.sun.star.lang.XSingleComponentFactory;
import com.sun.star.registry.XRegistryKey;
import com.sun.star.lib.uno.helper.WeakBase;
import com.sun.star.text.TextMarkupType;


public final class NewSmartTag extends WeakBase
implements com.sun.star.smarttags.XSmartTagRecognizer,
com.sun.star.lang.XServiceInfo
{
private final XComponentContext m_xContext;
private static final String m_SmartTagType = "com.example#newsmarttag";
private static final String m_implementationName = NewSmartTag.class.getName();
private static final String[] m_serviceNames = {
"com.sun.star.smarttags.SmartTagRecognizer" };


public NewSmartTag( XComponentContext context )
{
m_xContext = context;
};

public static XSingleComponentFactory __getComponentFactory( String sImplementationName ) {
XSingleComponentFactory xFactory = null;

if ( sImplementationName.equals( m_implementationName ) )
xFactory = Factory.createComponentFactory(NewSmartTag.class, m_serviceNames);
return xFactory;
}

public static boolean __writeRegistryServiceInfo( XRegistryKey xRegistryKey ) {
return Factory.writeRegistryServiceInfo(m_implementationName,
m_serviceNames,
xRegistryKey);
}

// com.sun.star.lang.XInitialization:
public void initialize(Object[] aArguments) throws com.sun.star.uno.Exception
{
// TODO: Insert your implementation for "initialize" here.
}

// com.sun.star.smarttags.XSmartTagRecognizer:
public int getSmartTagCount()
{
return 1;
}

public String getName(com.sun.star.lang.Locale aLocale)
{
// TODO: Exchange the default return implementation for "getName" !!!
// NOTE: Default initialized polymorphic structs can cause problems
// because of missing default initialization of primitive types of
// some C++ compilers or different Any initialization in Java and C++
// polymorphic structs.
return "Test Smart Tag";
}

public String getDescription(com.sun.star.lang.Locale aLocale)
{
// TODO: Exchange the default return implementation for "getDescription" !!!
// NOTE: Default initialized polymorphic structs can cause problems
// because of missing default initialization of primitive types of
// some C++ compilers or different Any initialization in Java and C++
// polymorphic structs.
return "Testing Smart Tags";
}

public String getSmartTagName(int nSmartTagIndex) throws com.sun.star.lang.IndexOutOfBoundsException
{
// TODO: Exchange the default return implementation for "getSmartTagName" !!!
// NOTE: Default initialized polymorphic structs can cause problems
// because of missing default initialization of primitive types of
// some C++ compilers or different Any initialization in Java and C++
// polymorphic structs.
return m_SmartTagType;
}

public String getSmartTagDownloadURL(int nSmartTagIndex) throws com.sun.star.lang.IndexOutOfBoundsException
{
// TODO: Exchange the default return implementation for "getSmartTagDownloadURL" !!!
// NOTE: Default initialized polymorphic structs can cause problems
// because of missing default initialization of primitive types of
// some C++ compilers or different Any initialization in Java and C++
// polymorphic structs.
return new String();
}

public void recognize(String aText, int nStart, int nLength, com.sun.star.smarttags.SmartTagRecognizerMode eDataType, com.sun.star.lang.Locale aLocale, com.sun.star.text.XTextMarkup xTextMarkup, String aApplicationName, com.sun.star.frame.XController xController, com.sun.star.i18n.XBreakIterator xTokenizer)
{
final int nEndPos = nStart + nLength;
Boundary aWordBounds = xTokenizer.getWordBoundary( aText, nStart, aLocale, WordType.DICTIONARY_WORD, true );
while (aWordBounds.startPos < aWordBounds.endPos && aWordBounds.endPos <=nEndPos)
{
final String aWord = aText.substring(aWordBounds.startPos, aWordBounds.endPos);
if(aWord.equalsIgnoreCase("David"))
{
XStringKeyMap xProps = null;
xTextMarkup.commitTextMarkup(TextMarkupType.SMARTTAG,
m_SmartTagType,
aWordBounds.startPos,
aWordBounds.endPos = aWordBounds.startPos,
xProps);

}
aWordBounds = xTokenizer.nextWord( aText, aWordBounds.startPos, aLocale, WordType.DICTIONARY_WORD );
}
}

public boolean hasPropertyPage(int nSmartTagIndex, com.sun.star.lang.Locale aLocale) throws com.sun.star.lang.IndexOutOfBoundsException
{
// TODO: Exchange the default return implementation for "hasPropertyPage" !!!
// NOTE: Default initialized polymorphic structs can cause problems
// because of missing default initialization of primitive types of
// some C++ compilers or different Any initialization in Java and C++
// polymorphic structs.
return false;
}

public void displayPropertyPage(int nSmartTagIndex, com.sun.star.lang.Locale aLocale) throws com.sun.star.lang.IndexOutOfBoundsException
{
// TODO: Insert your implementation for "displayPropertyPage" here.
}

// com.sun.star.lang.XServiceInfo:
public String getImplementationName() {
return m_implementationName;
}

public boolean supportsService( String sService ) {
int len = m_serviceNames.length;

for( int i=0; i < len; i++) {
if (sService.equals(m_serviceNames[i]))
return true;
}
return false;
}

public String[] getSupportedServiceNames() {
return m_serviceNames;
}

}

The recognize function is pretty much the only part that is coded.
First we define the length of the document, then tokenize that string dividing each word. We then set each word as our test and compare it to our string (in this case it is "David" but we could easily replace this with a method with regular expressions. We then set that text to the markup if it matches and then we get the next word. Getting the next word is important because it will give you an infinite loop if you do not.

The other methods are mostly definition methods such as getName, or getDescription and no coding is required to create them.

1 comment:

  1. Informative posting! Please continue digging into the source code and blogging about your discoveries.

    ReplyDelete