Tag: Ariba

Develop new custom Ariba portlet for your dashboard

With Ariba 9r1 you can customize your dashboard to add/edit the content which is super cool. The Ariba dashboard is made of portlet, each portlet is defined from an xml file, Ariba documents how to create new portlet but the different examples given in the documentation always refer to another web page, which is nice but limited if you want to have your own data displayed in a portlet.
In this example, I will write a portlet to pull some exchange rate between different currencies and display them to the user.
Basically and to keep it short, a portlet is defined in xml file and the content of the portlet is nothing more than an Ariba component (awl)

 

1. Define your portlet in config/variants/Plain/portlets/Portlet.xml

<PortletProviders>
    <PortletProvider stringFile="&lt;ProviderURL&gt;/ad/stringFile/PortletProviderActions?stringFile=ariba.analytics.portlets">
        <UniqueName>FHSolution Ariba Sandbox</UniqueName>
        <DisplayName>FHSolution Ariba Sandbox - Portlet Example</DisplayName>
        <Description>Custom content provided by www.fhsolution.com</Description>
        <HttpUR<&HttpURL;</HttpUR<
        <ServerUR<&ServerURL;</ServerUR<
        <Portlets>
            <Portlet>
                <UniqueName>PortletDemo</UniqueName>
                <DisplayName>Demo Ariba Portlet</DisplayName>
                <Description>Ariba Custom Portlet pulling financial exchange rate data</Description>
                <Controller>&lt;ProviderURL&gt;/ad/&lt;action&gt;/config.sandbox.dashboard.DemoPortletController</Controller>
                <ContentType>HTML</ContentType>
                <IsSingleton>true</IsSingleton>
                <IsEditable>false</IsEditable>
                <IsTOC>false</IsTOC>
                <SetupRequired>true</SetupRequired>
            </Portlet>
        </Portlets>
    </PortletProvider>
</PortletProviders>


In my example, I am using the analytics portlet provider so the portlet controller I am writing will extend AnalysisPortletController

2. Define the controller config.sandbox.dashboard.DemoPortletController

public class DemoPortletController extends AnalysisPortletController {

    protected boolean isUserAuthorizedForContent(User realUser, User effectiveUser) {
        return super.isUserAuthorizedForContent(realUser, effectiveUser);
    }

    @Override
    protected String editComponentName() {
        return null;
    }

    @Override
    protected String viewComponentName() {
        return DemoPortletContent.class.getName();
    }

    protected String portletTypeName () {
        return "Ariba Portlet Demo";
    }
}

The 2 main methods are

    protected String editComponentName() 

and

    protected String viewComponentName()

In this example, I only want to display information and the users cannot edit the component (you could imagine the user can edit the component to select the currency he wants to have appear) The viewComponentName refers to the awl component defined to display the exchange rate

3. Writing the portlet component

If you never wrote an awl component, it is (generally) made of 2 files :

  • The awl view
  • The corresponding java model

It is good practice (and the default) to have the 2 files in the same package/corresponding directory even if you can override some methods to have the awl in the directory you want.

In my case, the awl will be define in config/sandbox/dashboard/

<awconditional iftrue="$hasErrors">
    <span class="error">
        <awlocal key="a001">
            Error getting content for demo portlet.
        </awlocal>
    </span>
    <awelse equalnull="$content">
        <awlocal key="a002">
          The webservice site is not accessible and rendering of the portlet is not possible.
        </awlocal>
    <awelse>
       <awprimitivestring value="$content"/>
    </awelse>
    </awelse>
</awconditional>

The java model class will be define in package config.sandbox.dashboard :

public class DemoPortletContent extends PortletContent {

    public String _content;
    public boolean _hasErrors;

    public void initialize(PortletConfig portletConfig) {
        super.initialize(portletConfig);
        _content = null;
        _hasErrors = false;
        try {
            _content = getContent();
        } catch (IOException ex) {
            _hasErrors = true;
        }
    }

    public final static String getContent() throws IOException {
        String content = "";

        content += Fmt.S("1 EUR = %s USD<br/>", getRate("EUR", "USD"));
        content += Fmt.S("1 EUR = %s CHF<br/>", getRate("EUR", "CHF"));
        content += Fmt.S("1 EUR = %s GBP<br/>", getRate("EUR", "GBP"));

        return content;
    }

    /**
     * @see ariba.portlet.component.PortletContent#getContentType()
     */
    @Override
    public String getContentType() {
        return Constants.TypeHTML;
    }
    ...

It is not the scope of this post but here is the method to retrieve the currency rate (I know there are better methods but for the purpose of this blog it works fine) – if you are interested you can review the DemoPortletContent.java file

4. Add your portlet to the dashboard

You will need to restart your Ariba instance and after that you can add your new content to the dashboard
select the content to add :

Adding content to dashboard

And see your new portlet added on the dasboard :

New portlet on dashboard

Happy coding,

Fred

Tags: Ariba
Comments 0 | Views: 0 | Read more...

Remote debugging with Eclipse for Ariba development

Hello everyone,

I believe most people will already know it but for new comers on Ariba development, it can be of an help.

If you develop a lot on Java for your Ariba customization you might want to set up remote debugging (I do it anyway for any new instances that I set up) so you can actually debug your code and do not need tons of logging.

1. Modify the launch of your instance (can be sourcing (upstream) or buyer (downstream)) , so for example with weblogic modify the config.xml and in the serverstart tag change the Arguments property to add the following arguments "-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=<port>" so the ServerStart will look like

  
<server>
    <name>asmserver1</name>
    ....
    <listen-address>127.0.0.1</listen-address>
    <server-start>
      <class-path>...</class-path>
      <arguments>-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=50005 -Xms256m -Xmx512m -Xss1m -XX:MaxPermSize=256M -Dweblogic.net.http.URLStreamHandlerFactory=ariba.util.net.URLStreamHandlerFactory -Dariba.server.home=D:\ariba\customer9r1\Sandbox\Sourcing\Server</arguments>
</server-start>
</server>

2. Configure Eclipse

go to Run/debug...
create a new Remote Java Application
select your ariba project and under connection properties,
select Host : 127.0.0.1 (it must match the value you have for the listen-address argument)
Port : 50005

click Apply

14-10-2011 09-02-23


If the parameters are not correct and eclipse cannot link to the JVM it will pop up an error message.

14-10-2011 09-24-08


Most probably the port is already in use or one of the parameter is not correct and does not match with your configuration.

3. In your java file, just put breakpoint where you want your code to stop (make sure your build is set up to compile with the debug flag set to true)

when everything is configured :

  • start eclipse
  • start your ariba instance
  • launch debug

when the program will encounter a breakpoint, it will stop and pop up eclipse debug view.

14-10-2011 09-09-09

 

of course this is only for dev purpose and should not be use in any case on prod instance

 

Hope this helps,

Fred

Tags: Ariba, Java
Comments 4 | Views: 4053 | Read more...

Ariba JavaScript: Export Hierarchy Objects In CSV

Ariba includes in its meta model a number of hierarchical objects (ie: commodity, department, region …) which handles a hierarchy with a parent/child mechanism, this is really nice as it allows you to have an undefined number of level in your hierarchy and not a frozen structure.

However when you talk to business people, in many situation, the hierarchical model is indeed frozen (look the unspsc with up to 6 levels, the department class to represent the organization of the customer) so once you have implemented the structure in the system you do not get the level of a given object and it’s really difficult to represent the object in its original form.

The following Javascript will write in a csv file the CommoditCode object keeping the hierarchy of all objects:

var Log                   = ariba.util.log.Log;
var AQLQuery              = ariba.base.core.aql.AQLQuery;
var AQLOptions            = ariba.base.core.aql.AQLOptions;
var AQLResultCollection   = ariba.base.core.aql.AQLResultCollection;
var BaseId                = ariba.base.core.BaseId;
var Base                  = ariba.base.core.Base;
var Partition             = ariba.base.core.Partition;
var Locale                = java.util.Locale;
var ListUtil              = ariba.util.core.ListUtil;

var File       = java.io.File;
var FileUtil   = ariba.util.core.FileUtil;
var FileWriter = java.io.FileWriter;

// start from the main root of the tree
var queryText = 
  "select cc from ariba.basic.core.CommodityCode cc include inactive " +
  "where cc.Parent Is Null";

var query = AQLQuery.parseQuery(queryText);

var option = new AQLOptions(Partition.None);
option.setUserLocale(Locale.ENGLISH);
option.setUserPartition(Partition.None);

// define the file where results will be output
var sourceFile = 
  new File("config/variants/Plain/partitions/None/data/QueryReport/cc_super_cool.csv");
FileUtil.createDirsForFile(sourceFile);
var fileOut = new FileWriter(sourceFile);

// run the query and loop through results
var result = Base.getService().executeQuery(query, option);
while (result.next()) {
    var cc = Base.getSession().objectFromId(result.getObject(0));
    var parentList = ListUtil.list();
    writeCC(parentList, cc);
}
result.close();
fileOut.close();

/*
 * write a cc object : one cc line is represented with all its hierarchy
 * recursive function to loop through all objects which have child
 */
function writeCC(parentList, cc) {
    // 1.write active status and hierarchy path
    fileOut.write(cc.getActive() + "," + cc.getHierarchyPath() + ",");

    // 2.write parent list structure
    writeParentList(parentList);

    // 3.write cc info – this can be changed depending the object
    fileOut.write(cc.getDomain() + "," + cc.getUniqueName() + "," + cc.getName() + "\n");

    // 4.call on new list
    var childccList = getChildccFor (cc);
    if (!childccList.isEmpty()) {
        var newList = ListUtil.list();
        newList = ListUtil.copyList(parentList);
        newList.add(cc);
        for (var i=0; i<childccList.size(); i++) {
            var childcc = childccList.get(i);
            writeCC(newList, childcc);
        }
    }
}

/*
 * write the hierarchy
 */
function writeParentList (list) {
    for (var i=0; i<list.size(); i++) {
        var cc = list.get(i);
        fileOut.write(cc.getDomain() + "," + cc.getUniqueName() + "," + cc.getName() + ",");
    }
}

/*
 * search and return the child object for a given parent
 */
function getChildccFor (parentcc) {

    var queryChildText = 
      "select cc from ariba.basic.core.CommodityCode cc include inactive " +
      "where cc.Parent = BaseId('" + parentcc.getBaseId().toDBString() + "')";
    var queryChild = AQLQuery.parseQuery(queryChildText);

    var optionChild = new AQLOptions(Partition.None);
    optionChild.setUserLocale(Locale.ENGLISH);
    optionChild.setUserPartition(Partition.None);

    var childList = ListUtil.list();
    var resultChild = Base.getService().executeQuery(queryChild, optionChild);
    while (resultChild.next()) {
        var cc = Base.getSession().objectFromId(resultChild.getObject(0));
        childList.add(cc);
    }
    resultChild.close();
    return childList;
}

Note : the query written is a bit lazy and it would be more effective to query the field you are interested to, but this is for demo purpose.
you could also use the Formatting API from Ariba (Fmt class) rather than using the + concatenate of String objects.

You can then import the csv file in xl and run the filtering from there:

Tags: Ariba
Comments 11 | Views: 5763 | Read more...

CSV Editor Eclipse Plugin

The first version of the csv plugin editor has been released and is available at http://code.google.com/p/csvedit/downloads/list

If you are dealing with csv files in your Eclipse project, you might want to take a look at this plugin which will make it easy .
Among the feature you will find:
- view csv file in source editor or table editor
- easy search in table view
- customize view with filtering column
- sorting column
- easily insert/delete rows

Tags: Java, Ariba
Comments 5 | Views: 7178 | Read more...

Welcome

Welcome in FHSolution,

This is the first post as the site is launched. I'll speak about Ariba and Java technologies, try to share some good tips regarding the Ariba implementation that I gathered with my experience, and see how it evolves.

Thanks,

Comments 5 | Views: 2796 | Read more...